From 773eda1929a65a68c3e6d664b74bc536ff22868f Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Fri, 12 Sep 2003 18:41:29 +0000 Subject: [PATCH] Okay, all. This is the TexturePaint 1.1 GIMP plugin, modified by me long ago to work under GIMP 1.2.x -- at taniwha's urging, I am checking this into CVS. You need libgtk+ v1.2, libgtkglarea v5, libgimp v1.2 (or thereabouts) to get this to work. --- tools/texpaint/COPYING | 340 ++++++ tools/texpaint/Makefile.am | 35 + tools/texpaint/Pixmaps/begin.xpm | 21 + tools/texpaint/Pixmaps/end.xpm | 21 + tools/texpaint/Pixmaps/pause.xpm | 21 + tools/texpaint/Pixmaps/play.xpm | 21 + tools/texpaint/Pixmaps/question.xpm | 69 ++ tools/texpaint/Pixmaps/stop.xpm | 21 + tools/texpaint/Pixmaps/warning.xpm | 69 ++ tools/texpaint/README | 59 + tools/texpaint/acinclude.m4 | 407 +++++++ tools/texpaint/bootstrap | 94 ++ tools/texpaint/config.h.in | 27 + tools/texpaint/configure.ac | 41 + tools/texpaint/dialog.glade | 1299 ++++++++++++++++++++++ tools/texpaint/gladesig.c | 189 ++++ tools/texpaint/gladesig.h | 79 ++ tools/texpaint/gladesrc.c | 706 ++++++++++++ tools/texpaint/gladesrc.h | 45 + tools/texpaint/main.c | 423 ++++++++ tools/texpaint/model.h | 81 ++ tools/texpaint/model1.c | 302 ++++++ tools/texpaint/model2.c | 357 +++++++ tools/texpaint/open.c | 204 ++++ tools/texpaint/pack.c | 278 +++++ tools/texpaint/pack.h | 32 + tools/texpaint/q1pal.h | 258 +++++ tools/texpaint/texturepaint.c | 1540 +++++++++++++++++++++++++++ tools/texpaint/texturepaint.h | 181 ++++ tools/texpaint/trackball.c | 324 ++++++ tools/texpaint/trackball.h | 78 ++ 31 files changed, 7622 insertions(+) create mode 100644 tools/texpaint/COPYING create mode 100644 tools/texpaint/Makefile.am create mode 100644 tools/texpaint/Pixmaps/begin.xpm create mode 100644 tools/texpaint/Pixmaps/end.xpm create mode 100644 tools/texpaint/Pixmaps/pause.xpm create mode 100644 tools/texpaint/Pixmaps/play.xpm create mode 100644 tools/texpaint/Pixmaps/question.xpm create mode 100644 tools/texpaint/Pixmaps/stop.xpm create mode 100644 tools/texpaint/Pixmaps/warning.xpm create mode 100644 tools/texpaint/README create mode 100644 tools/texpaint/acinclude.m4 create mode 100755 tools/texpaint/bootstrap create mode 100644 tools/texpaint/config.h.in create mode 100644 tools/texpaint/configure.ac create mode 100644 tools/texpaint/dialog.glade create mode 100644 tools/texpaint/gladesig.c create mode 100644 tools/texpaint/gladesig.h create mode 100644 tools/texpaint/gladesrc.c create mode 100644 tools/texpaint/gladesrc.h create mode 100644 tools/texpaint/main.c create mode 100644 tools/texpaint/model.h create mode 100644 tools/texpaint/model1.c create mode 100644 tools/texpaint/model2.c create mode 100644 tools/texpaint/open.c create mode 100644 tools/texpaint/pack.c create mode 100644 tools/texpaint/pack.h create mode 100644 tools/texpaint/q1pal.h create mode 100644 tools/texpaint/texturepaint.c create mode 100644 tools/texpaint/texturepaint.h create mode 100644 tools/texpaint/trackball.c create mode 100644 tools/texpaint/trackball.h diff --git a/tools/texpaint/COPYING b/tools/texpaint/COPYING new file mode 100644 index 000000000..60549be51 --- /dev/null +++ b/tools/texpaint/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/tools/texpaint/Makefile.am b/tools/texpaint/Makefile.am new file mode 100644 index 000000000..19b995b07 --- /dev/null +++ b/tools/texpaint/Makefile.am @@ -0,0 +1,35 @@ + +AUTOMAKE_OPTIONS = foreign + +bin_PROGRAMS = texturepaint + +texturepaint_SOURCES = \ + main.c \ + model.h \ + model1.c \ + model2.c \ + open.c \ + pack.c \ + pack.h \ + q1pal.h \ + texturepaint.c \ + texturepaint.h \ + trackball.c \ + trackball.h \ + gladesrc.c \ + gladesrc.h \ + gladesig.h + +EXTRA_DIST= \ + dialog.glade \ + gladesig.c \ + Pixmaps/begin.xpm \ + Pixmaps/end.xpm \ + Pixmaps/play.xpm \ + Pixmaps/pause.xpm \ + Pixmaps/question.xpm \ + Pixmaps/stop.xpm \ + Pixmaps/warning.xpm + + + diff --git a/tools/texpaint/Pixmaps/begin.xpm b/tools/texpaint/Pixmaps/begin.xpm new file mode 100644 index 000000000..43651659e --- /dev/null +++ b/tools/texpaint/Pixmaps/begin.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char * begin_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ... .. ", +" ... ... ", +" ... ..... ", +" ... ....... ", +" ............ ", +" ............ ", +" ............ ", +" ... ....... ", +" ... ..... ", +" ... ... ", +" ... .. ", +" ", +" ", +" "}; diff --git a/tools/texpaint/Pixmaps/end.xpm b/tools/texpaint/Pixmaps/end.xpm new file mode 100644 index 000000000..6a3443216 --- /dev/null +++ b/tools/texpaint/Pixmaps/end.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char * end_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" .. ... ", +" ... ... ", +" ..... ... ", +" ....... ... ", +" ............ ", +" ............ ", +" ............ ", +" ....... ... ", +" ..... ... ", +" ... ... ", +" .. ... ", +" ", +" "}; diff --git a/tools/texpaint/Pixmaps/pause.xpm b/tools/texpaint/Pixmaps/pause.xpm new file mode 100644 index 000000000..5b11c0d5e --- /dev/null +++ b/tools/texpaint/Pixmaps/pause.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char * pause_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ..... ..... ", +" ", +" ", +" "}; diff --git a/tools/texpaint/Pixmaps/play.xpm b/tools/texpaint/Pixmaps/play.xpm new file mode 100644 index 000000000..e27c5fe8f --- /dev/null +++ b/tools/texpaint/Pixmaps/play.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char * play_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" .. ", +" .... ", +" ...... ", +" ....... ", +" ......... ", +" ......... ", +" ....... ", +" ...... ", +" .... ", +" .. ", +" ", +" ", +" "}; diff --git a/tools/texpaint/Pixmaps/question.xpm b/tools/texpaint/Pixmaps/question.xpm new file mode 100644 index 000000000..a8133ed86 --- /dev/null +++ b/tools/texpaint/Pixmaps/question.xpm @@ -0,0 +1,69 @@ +/* XPM */ +static char * question_xpm[] = { +"64 64 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ....... ", +" ............ ", +" .... ...... ", +" ... ...... ", +" ... ...... ", +" ... ...... ", +" .... ...... ", +" .... ...... ", +" ..... ...... ", +" ...... ...... ", +" ...... ...... ", +" ..... ...... ", +" .... ..... ", +" ...... ", +" ...... ", +" ..... ", +" ...... ", +" ..... ", +" ..... ", +" .... ", +" .... ", +" ... ", +" .... ", +" ... ", +" .. ", +" .. ", +" . ", +" .. ", +" .. ", +" .. ", +" .. ", +" ", +" ", +" ", +" ", +" ", +" ... ", +" ..... ", +" ....... ", +" ....... ", +" ....... ", +" ..... ", +" ... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/tools/texpaint/Pixmaps/stop.xpm b/tools/texpaint/Pixmaps/stop.xpm new file mode 100644 index 000000000..6df726afe --- /dev/null +++ b/tools/texpaint/Pixmaps/stop.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char * stop_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ........... ", +" ", +" ", +" "}; diff --git a/tools/texpaint/Pixmaps/warning.xpm b/tools/texpaint/Pixmaps/warning.xpm new file mode 100644 index 000000000..b44689816 --- /dev/null +++ b/tools/texpaint/Pixmaps/warning.xpm @@ -0,0 +1,69 @@ +/* XPM */ +static char * warning_xpm[] = { +"64 64 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ... ", +" ..... ", +" ....... ", +" ....... ", +" ....... ", +" ....... ", +" ....... ", +" ....... ", +" ....... ", +" ...... ", +" ..... ", +" ..... ", +" ..... ", +" ..... ", +" ..... ", +" ..... ", +" ..... ", +" ..... ", +" ..... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" . ", +" . ", +" . ", +" ", +" ", +" ", +" ", +" ", +" ... ", +" ..... ", +" ....... ", +" ....... ", +" ....... ", +" ..... ", +" ... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/tools/texpaint/README b/tools/texpaint/README new file mode 100644 index 000000000..80c7216f5 --- /dev/null +++ b/tools/texpaint/README @@ -0,0 +1,59 @@ + +----------------------- +Texture Paint 1.1 +by Uwe Maurer +Jan 19 1998 +-------------------------- + +Texture Paint homepage: +http://home.t-online.de/home/uwe_maurer/texpaint.htm + +Texture Paint is a GIMP plug-in. With Texture Paint you can paint +on Quake I and Quake II models and the plug-in calculates the texture for you. +You can also paint directly on the texture and view the result in +the 3D Window. + +Texture Paint uses the MD2- and PAK-file code from GiMd2Viewer +(http://www.mygale.org/~bbrox/GiMd2Viewer/) +by Lionel ULMER + +Autoconf files by Zach Beane + + +------------------------------------------------------------ + +Installation: + + 1 . You need + + - the GIMP + http://www.gimp.org + + - the Gtk+ library + http://www.gtk.org + + - an implementation of OpenGL or Mesa + http://www.ssec.wisc.edu/~brianp/Mesa.html + + - the Gtk GLAreaWidget + http://www.student.oulu.fi/~jlof/gtkglarea/ + + 2. run "./configure" and "make" : + + ./configure + make + + 4. copy texturepaint into your gimp plug-in directory: + + gimptool --install-bin texturepaint + + or + cp texturepaint $HOME/.gimp/plug-ins/ + + + 5. Start the GIMP + and have fun! + +------------------------------------- +Uwe Maurer - uwe_maurer@t-online.de +-------------------------------------- diff --git a/tools/texpaint/acinclude.m4 b/tools/texpaint/acinclude.m4 new file mode 100644 index 000000000..0aded5348 --- /dev/null +++ b/tools/texpaint/acinclude.m4 @@ -0,0 +1,407 @@ +# Configure paths for GTK+ +# Owen Taylor 97-11-3 + +dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) +dnl Test for GTK, and define GTK_CFLAGS and GTK_LIBS +dnl +AC_DEFUN(AM_PATH_GTK, +[dnl +dnl Get the cflags and libraries from the gtk-config script +dnl +AC_ARG_WITH(gtk-prefix,[ --with-gtk-prefix=PFX Prefix where GTK is installed (optional)], + gtk_config_prefix="$withval", gtk_config_prefix="") +AC_ARG_WITH(gtk-exec-prefix,[ --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)], + gtk_config_exec_prefix="$withval", gtk_config_exec_prefix="") +AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program], + , enable_gtktest=yes) + + for module in . $4 + do + case "$module" in + gthread) + gtk_config_args="$gtk_config_args gthread" + ;; + esac + done + + if test x$gtk_config_exec_prefix != x ; then + gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix" + if test x${GTK_CONFIG+set} != xset ; then + GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config + fi + fi + if test x$gtk_config_prefix != x ; then + gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix" + if test x${GTK_CONFIG+set} != xset ; then + GTK_CONFIG=$gtk_config_prefix/bin/gtk-config + fi + fi + + AC_PATH_PROG(GTK_CONFIG, gtk-config, no) + min_gtk_version=ifelse([$1], ,0.99.7,$1) + AC_MSG_CHECKING(for GTK - version >= $min_gtk_version) + no_gtk="" + if test "$GTK_CONFIG" = "no" ; then + no_gtk=yes + else + GTK_CFLAGS=`$GTK_CONFIG $gtk_config_args --cflags` + GTK_LIBS=`$GTK_CONFIG $gtk_config_args --libs` + gtk_config_major_version=`$GTK_CONFIG $gtk_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + gtk_config_minor_version=`$GTK_CONFIG $gtk_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + gtk_config_micro_version=`$GTK_CONFIG $gtk_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_gtktest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GTK_CFLAGS" + LIBS="$GTK_LIBS $LIBS" +dnl +dnl Now check if the installed GTK is sufficiently new. (Also sanity +dnl checks the results of gtk-config to some extent +dnl + rm -f conf.gtktest + AC_TRY_RUN([ +#include +#include +#include + +int +main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.gtktest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = g_strdup("$min_gtk_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_gtk_version"); + exit(1); + } + + if ((gtk_major_version != $gtk_config_major_version) || + (gtk_minor_version != $gtk_config_minor_version) || + (gtk_micro_version != $gtk_config_micro_version)) + { + printf("\n*** 'gtk-config --version' returned %d.%d.%d, but GTK+ (%d.%d.%d)\n", + $gtk_config_major_version, $gtk_config_minor_version, $gtk_config_micro_version, + gtk_major_version, gtk_minor_version, gtk_micro_version); + printf ("*** was found! If gtk-config was correct, then it is best\n"); + printf ("*** to remove the old version of GTK+. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If gtk-config was wrong, set the environment variable GTK_CONFIG\n"); + printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n"); + printf("*** before re-running configure\n"); + } +#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION) + else if ((gtk_major_version != GTK_MAJOR_VERSION) || + (gtk_minor_version != GTK_MINOR_VERSION) || + (gtk_micro_version != GTK_MICRO_VERSION)) + { + printf("*** GTK+ header files (version %d.%d.%d) do not match\n", + GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); + printf("*** library (version %d.%d.%d)\n", + gtk_major_version, gtk_minor_version, gtk_micro_version); + } +#endif /* defined (GTK_MAJOR_VERSION) ... */ + else + { + if ((gtk_major_version > major) || + ((gtk_major_version == major) && (gtk_minor_version > minor)) || + ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** An old version of GTK+ (%d.%d.%d) was found.\n", + gtk_major_version, gtk_minor_version, gtk_micro_version); + printf("*** You need a version of GTK+ newer than %d.%d.%d. The latest version of\n", + major, minor, micro); + printf("*** GTK+ is always available from ftp://ftp.gtk.org.\n"); + printf("***\n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the gtk-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of GTK+, but you can also set the GTK_CONFIG environment to point to the\n"); + printf("*** correct copy of gtk-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +],, no_gtk=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_gtk" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$GTK_CONFIG" = "no" ; then + echo "*** The gtk-config script installed by GTK could not be found" + echo "*** If GTK was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the GTK_CONFIG environment variable to the" + echo "*** full path to gtk-config." + else + if test -f conf.gtktest ; then + : + else + echo "*** Could not run GTK test program, checking why..." + CFLAGS="$CFLAGS $GTK_CFLAGS" + LIBS="$LIBS $GTK_LIBS" + AC_TRY_LINK([ +#include +#include +], [ return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding GTK or finding the wrong" + echo "*** version of GTK. If it is not finding GTK, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***" + echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that" + echo "*** came with the system with the command" + echo "***" + echo "*** rpm --erase --nodeps gtk gtk-devel" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means GTK was incorrectly installed" + echo "*** or that you have moved GTK since it was installed. In the latter case, you" + echo "*** may want to edit the gtk-config script: $GTK_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + GTK_CFLAGS="" + GTK_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(GTK_CFLAGS) + AC_SUBST(GTK_LIBS) + rm -f conf.gtktest +]) + +# Configure paths for GIMP +# Manish Singh 98-6-11 +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_GIMP([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for GIMP, and define GIMP_CFLAGS and GIMP_LIBS +dnl +AC_DEFUN(AM_PATH_GIMP, +[dnl +dnl Get the cflags and libraries from the gimptool script +dnl +AC_ARG_WITH(gimp-prefix,[ --with-gimp-prefix=PFX Prefix where GIMP is installed (optional)], + gimptool_prefix="$withval", gimptool_prefix="") +AC_ARG_WITH(gimp-exec-prefix,[ --with-gimp-exec-prefix=PFX Exec prefix where GIMP is installed (optional)], + gimptool_exec_prefix="$withval", gimptool_exec_prefix="") +AC_ARG_ENABLE(gimptest, [ --disable-gimptest Do not try to compile and run a test GIMP program], + , enable_gimptest=yes) + + if test x$gimptool_exec_prefix != x ; then + gimptool_args="$gimptool_args --exec-prefix=$gimptool_exec_prefix" + if test x${GIMPTOOL+set} != xset ; then + GIMPTOOL=$gimptool_exec_prefix/bin/gimptool + fi + fi + if test x$gimptool_prefix != x ; then + gimptool_args="$gimptool_args --prefix=$gimptool_prefix" + if test x${GIMPTOOL+set} != xset ; then + GIMPTOOL=$gimptool_prefix/bin/gimptool + fi + fi + + AC_PATH_PROG(GIMPTOOL, gimptool, no) + min_gimp_version=ifelse([$1], ,1.0.0,$1) + AC_MSG_CHECKING(for GIMP - version >= $min_gimp_version) + no_gimp="" + if test "$GIMPTOOL" = "no" ; then + no_gimp=yes + else + GIMP_CFLAGS=`$GIMPTOOL $gimptool_args --cflags` + GIMP_LIBS=`$GIMPTOOL $gimptool_args --libs` + + GIMP_CFLAGS_NOUI=`$GIMPTOOL $gimptool_args --cflags-noui` + noui_test=`echo $GIMP_CFLAGS_NOUI | sed 's/^\(Usage\).*/\1/'` + if test "$noui_test" = "Usage" ; then + GIMP_CFLAGS_NOUI=$GIMP_CFLAGS + GIMP_LIBS_NOUI=$GIMP_LIBS + else + GIMP_LIBS_NOUI=`$GIMPTOOL $gimptool_args --libs-noui` + fi + + GIMP_DATA_DIR=`$GIMPTOOL $gimptool_args --gimpdatadir` + GIMP_PLUGIN_DIR=`$GIMPTOOL $gimptool_args --gimpplugindir` + nodatadir_test=`echo $GIMP_DATA_DIR | sed 's/^\(Usage\).*/\1/'` + if test "$nodatadir_test" = "Usage" ; then + GIMP_DATA_DIR="" + GIMP_PLUGIN_DIR="" + fi + + gimptool_major_version=`$GIMPTOOL $gimptool_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + gimptool_minor_version=`$GIMPTOOL $gimptool_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + gimptool_micro_version=`$GIMPTOOL $gimptool_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_gimptest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GIMP_CFLAGS" + LIBS="$LIBS $GIMP_LIBS" +dnl +dnl Now check if the installed GIMP is sufficiently new. (Also sanity +dnl checks the results of gimptool to some extent +dnl + rm -f conf.gimptest + AC_TRY_RUN([ +#include +#include + +#include + +#ifndef GIMP_CHECK_VERSION +#define GIMP_CHECK_VERSION(major, minor, micro) \ + (GIMP_MAJOR_VERSION > (major) || \ + (GIMP_MAJOR_VERSION == (major) && GIMP_MINOR_VERSION > (minor)) || \ + (GIMP_MAJOR_VERSION == (major) && GIMP_MINOR_VERSION == (minor) && \ + GIMP_MICRO_VERSION >= (micro))) +#endif + +#if GIMP_CHECK_VERSION(1,1,24) +GimpPlugInInfo +#else +GPlugInInfo +#endif +PLUG_IN_INFO = +{ + NULL, /* init_proc */ + NULL, /* quit_proc */ + NULL, /* query_proc */ + NULL /* run_proc */ +}; + +int main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.gimptest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = g_strdup("$min_gimp_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_gimp_version"); + exit(1); + } + + if (($gimptool_major_version > major) || + (($gimptool_major_version == major) && ($gimptool_minor_version > minor)) || + (($gimptool_major_version == major) && ($gimptool_minor_version == minor) && ($gimptool_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'gimptool --version' returned %d.%d.%d, but the minimum version\n", $gimptool_major_version, $gimptool_minor_version, $gimptool_micro_version); + printf("*** of GIMP required is %d.%d.%d. If gimptool is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If gimptool was wrong, set the environment variable GIMPTOOL\n"); + printf("*** to point to the correct copy of gimptool, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_gimp=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_gimp" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$GIMPTOOL" = "no" ; then + echo "*** The gimptool script installed by GIMP could not be found" + echo "*** If GIMP was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the GIMPTOOL environment variable to the" + echo "*** full path to gimptool." + else + if test -f conf.gimptest ; then + : + else + echo "*** Could not run GIMP test program, checking why..." + CFLAGS="$CFLAGS $GIMP_CFLAGS" + LIBS="$LIBS $GIMP_LIBS" + AC_TRY_LINK([ +#include +#include + +#ifndef GIMP_CHECK_VERSION +#define GIMP_CHECK_VERSION(major, minor, micro) \ + (GIMP_MAJOR_VERSION > (major) || \ + (GIMP_MAJOR_VERSION == (major) && GIMP_MINOR_VERSION > (minor)) || \ + (GIMP_MAJOR_VERSION == (major) && GIMP_MINOR_VERSION == (minor) && \ + GIMP_MICRO_VERSION >= (micro))) +#endif + +#if GIMP_CHECK_VERSION(1,1,24) +GimpPlugInInfo +#else +GPlugInInfo +#endif +PLUG_IN_INFO = +{ + NULL, /* init_proc */ + NULL, /* quit_proc */ + NULL, /* query_proc */ + NULL /* run_proc */ +}; +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding GIMP or finding the wrong" + echo "*** version of GIMP. If it is not finding GIMP, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means GIMP was incorrectly installed" + echo "*** or that you have moved GIMP since it was installed. In the latter case, you" + echo "*** may want to edit the gimptool script: $GIMPTOOL" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + GIMP_CFLAGS="" + GIMP_LIBS="" + GIMP_CFLAGS_NOUI="" + GIMP_LIBS_NOUI="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(GIMP_CFLAGS) + AC_SUBST(GIMP_LIBS) + AC_SUBST(GIMP_CFLAGS_NOUI) + AC_SUBST(GIMP_LIBS_NOUI) + AC_SUBST(GIMP_DATA_DIR) + AC_SUBST(GIMP_PLUGIN_DIR) + rm -f conf.gimptest +]) + diff --git a/tools/texpaint/bootstrap b/tools/texpaint/bootstrap new file mode 100755 index 000000000..ed2aa395f --- /dev/null +++ b/tools/texpaint/bootstrap @@ -0,0 +1,94 @@ +#! /bin/sh +cd `dirname $0` + +if test "$1" = "clean"; then + find . -name Makefile.in -print0 | xargs -r0 rm -f + find . -name '*~' -type f -print0 | xargs -r0 rm -f + find . -name '*.rej' -type f -print0 | xargs -r0 rm -f + find . -name '*.orig' -type f -print0 | xargs -r0 rm -f + rm -f aclocal.m4 build-stamp changelog-stamp config.cache config.log \ + config.status configure configure-stamp install-sh libtool missing \ + mkinstalldirs quakeforge-config quakeforge.lsm + rm -f compile config.guess config.sub depcomp ltmain.sh + rm -rf autom4te.cache + + cd - + find . -name Makefile -print0 | xargs -r0 rm -f + rm -f RPM/build_rpm RPM/quakeforge.conf RPM/quakeforge.spec RPM/rpmmacros + find . -name '*.o' -type f -print0 | xargs -r0 rm -f + find . -name '*.lo' -type f -print0 | xargs -r0 rm -f + find . -name '.libs' -type d -print0 | xargs -r0 rm -rf + find . -name '.deps' -type d -print0 | xargs -r0 rm -rf + exit 0 +fi +# Check libtoolize version, fix for Debian/Woody +if test x`uname` = xDarwin ; then + libtoolize=glibtoolize +else + libtoolize=libtoolize +fi +lt=`which $libtoolize` +if test -n "$lt" ; then + if test -x "$lt" ; then + LTIZE_VER=`$libtoolize --version | head -1 | sed 's/^[^0-9]*//'` + LTIZE_VER_MAJOR=`echo $LTIZE_VER | cut -f1 -d'.'` + LTIZE_VER_MINOR=`echo $LTIZE_VER | cut -f2 -d'.' | sed -e 's/[^0-9]//g'` + + if test "$LTIZE_VER_MAJOR" -lt "1"; then + echo "Libtool 1.4 or greater needed to build configure." + exit 1 + fi + if test "$LTIZE_VER_MAJOR" -eq "1" -a "$LTIZE_VER_MINOR" -lt "4" ; then + echo "Libtool 1.4 or greater needed to build configure." + exit 1 + fi + fi +else + echo Libtool not found. QuakeForge CVS requires libtool to bootstrap itself. + exit 1 +fi + +# Check Autoconf version +ac=`which autoconf` +if test -n "$ac" ; then + if test -x "$ac" ; then + AC_VER=`autoconf --version | head -1 | sed 's/^[^0-9]*//'` + AC_VER_MAJOR=`echo $AC_VER | cut -f1 -d'.'` + AC_VER_MINOR=`echo $AC_VER | cut -f2 -d'.' | sed 's/[^0-9]*$//'` + + if test "$AC_VER_MAJOR" -lt "2" ; then + echo "Autoconf 2.52 or greater needed to build configure." + exit 1 + fi + + if test "$AC_VER_MAJOR" -eq "2" -a "$AC_VER_MINOR" -lt "52" ; then + echo "Autoconf 2.52 or greater needed to build configure." + exit 1 + fi + fi +else + echo Autoconf not found. QuakeForge CVS requires autoconf to bootstrap itself. + exit 1 +fi + +am=`which automake` +if test -n "$am" ; then + if test -x "$am" ; then + AM_VER=`automake --version | head -1 | sed -e 's/automake (GNU automake) //' -e 's/\-p.*$//'` + AM_VER_MAJOR=`echo $AM_VER | cut -f1 -d.` + AM_VER_MINOR=`echo $AM_VER | cut -f2 -d.` + if test "$AM_VER_MAJOR" -lt "1"; then + echo "Automake 1.6 or greater needed to build makefiles." + exit 1 + fi + if test "$AM_VER_MAJOR" -eq "1" -a "$AM_VER_MINOR" -lt "6"; then + echo "Automake 1.6 or greater needed to build makefiles." + exit 1 + fi + fi +else + echo Automake not found. QuakeForge CVS requires automake to bootstrap itself. + exit 1 +fi + +aclocal && autoheader && $libtoolize --automake && automake --add-missing && autoconf diff --git a/tools/texpaint/config.h.in b/tools/texpaint/config.h.in new file mode 100644 index 000000000..dcfbe04ab --- /dev/null +++ b/tools/texpaint/config.h.in @@ -0,0 +1,27 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ +#undef PACKAGE +#undef VERSION + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING diff --git a/tools/texpaint/configure.ac b/tools/texpaint/configure.ac new file mode 100644 index 000000000..1e7a29b57 --- /dev/null +++ b/tools/texpaint/configure.ac @@ -0,0 +1,41 @@ +AC_INIT(texturepaint.c) +PACKAGE=texturepaint +VERSION=1.1 + +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) +AM_CONFIG_HEADER(config.h) + +AC_SUBST(VERSION) + +dnl Check for programs +AC_PROG_CC +AC_PATH_XTRA + +dnl Check for libs. + +dnl AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS"; LIBS="$LIBS $GTK_LIBS", +dnl AC_MSG_ERROR(*** Can't find gtk)) + +AC_CHECK_LIB(GL, glXChooseVisual, LIBS="$LIBS -lGL", + [AC_CHECK_LIB(MesaGL, glXChooseVisual, LIBS="$LIBS -lMesaGL", + AC_MSG_ERROR(*** Can't find OpenGL), + $X_PRE_LIBS $X_LIBS -lX11 -lXext -lm $X_EXTRA_LIBS)], + $X_PRE_LIBS $X_LIBS -lX11 -lXext -lm $X_EXTRA_LIBS) + +AC_CHECK_LIB(GLU, gluPerspective, LIBS="$LIBS -lGLU", + [AC_CHECK_LIB(MesaGLU, gluPerspective, LIBS="$LIBS -lMesaGLU", + AC_MSG_ERROR(*** Can't find libGLU), + $X_PRE_LIBS $X_LIBS -lX11 -lXext -lm $X_EXTRA_LIBS)], + $X_PRE_LIBS $X_LIBS -lX11 -lXext -lm $X_EXTRA_LIBS) + +AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS"; LIBS="$LIBS $GTK_LIBS", + AC_MSG_ERROR(*** Can't find GTK)) + +AC_CHECK_LIB(gtkgl, gtk_gl_area_begingl, LIBS="$LIBS -lgtkgl", + AC_MSG_ERROR(*** Can't find gtkglarea)) + +AM_PATH_GIMP(1.0.0, CFLAGS="$CFLAGS $GIMP_CFLAGS"; LIBS="$LIBS $GIMP_LIBS", + AC_MSG_ERROR(*** Can't find GIMP)) + +dnl Output stuff. +AC_OUTPUT(Makefile) diff --git a/tools/texpaint/dialog.glade b/tools/texpaint/dialog.glade new file mode 100644 index 000000000..ff847480a --- /dev/null +++ b/tools/texpaint/dialog.glade @@ -0,0 +1,1299 @@ + + + + + + GtkWindow + glwindow + + destroy + on_glwindow_destroy + + 3D Window + GTK_WINDOW_DIALOG + GTK_WIN_POS_NONE + True + True + False + + + Placeholder + + + + + GtkFileSelection + fileselection + 10 + + delete_event + on_fileselection_delete + + Select a PAK, MDL or MD2 file + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + True + False + True + False + + + GtkButton + FileSel:ok_button + ok_button1 + True + True + + clicked + on_ok_clicked + + + + + + GtkButton + FileSel:cancel_button + cancel_button1 + True + True + + clicked + on_cancel_clicked + + + + + + + GtkWindow + pakdialog + 4 + 256 + 256 + Select a MDL, MD2 or PCX file + GTK_WINDOW_DIALOG + GTK_WIN_POS_NONE + True + True + False + + + GtkVBox + vbox8 + False + 0 + + + GtkLabel + filename + + 0 + False + True + + + GTK_JUSTIFY_LEFT + 0 + 0.5 + 0 + 0 + + + + GtkScrolledWindow + scrolledwindow + 4 + + 0 + True + True + + GTK_SHADOW_IN + GTK_POLICY_ALWAYS + GTK_POLICY_ALWAYS + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + + Placeholder + + + + + GtkButton + open + 4 + + 0 + False + True + + True + + + + + GtkButton + close + 4 + + 0 + False + True + + True + + + + + + + GtkDialog + dialog + 2 + + destroy + on_dialog_destroy + + Texture Paint + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + True + True + False + + + GtkVBox + Dialog:vbox + dialog-vbox2 + False + 0 + + + GtkHBox + hbox7 + 4 + + 0 + False + True + + False + 0 + + + GtkLabel + label14 + + 0 + False + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkOptionMenu + models_menu + 4 + + 0 + True + True + + + 0 + + + + + GtkNotebook + notebook1 + 4 + + 0 + True + True + + True + True + True + GTK_POS_TOP + False + 3 + False + + + GtkVBox + vbox15 + False + 0 + + + GtkButton + button19 + 4 + + 0 + False + True + + True + + clicked + on_load_clicked + + + + + + GtkFrame + frame11 + + 0 + True + True + + + 0 + GTK_SHADOW_ETCHED_IN + + + GtkVBox + vbox17 + False + 0 + + + GtkHBox + hbox11 + 4 + + 0 + False + True + + False + 0 + + + GtkLabel + label30 + + 0 + False + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkOptionMenu + images_menu + 2 + + 0 + True + True + + + enter + on_images_menu_enter + + + 0 + + + + + GtkLabel + info + + 0 + False + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table4 + + 0 + False + True + + 2 + 2 + False + 0 + 0 + + + GtkLabel + l20 + + 0 + 1 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + + GTK_JUSTIFY_LEFT + 0 + 0.5 + 0 + 0 + + + + GtkLabel + l30 + + 0 + 1 + 1 + 2 + 0 + 0 + True + True + False + False + True + True + + + GTK_JUSTIFY_LEFT + 0 + 0.5 + 0 + 0 + + + + GtkSpinButton + width + + 1 + 2 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + True + False + 1 + 1 + 5000 + 1 + 10 + 10 + + + + GtkSpinButton + height + + 1 + 2 + 1 + 2 + 0 + 0 + True + True + False + False + True + True + + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + True + False + 1 + 1 + 5000 + 1 + 10 + 10 + + + + + GtkCheckButton + new_image + + 0 + False + True + + True + + False + True + + + + GtkButton + scale + + 0 + False + True + + True + + clicked + on_scale_clicked + + + + + + GtkButton + base_texture + + 0 + False + True + + True + + clicked + on_base_texture_clicked + + + + + + + + + GtkVBox + vbox16 + 4 + False + 0 + + + GtkButton + button21 + 4 + + 0 + False + True + + True + + clicked + on_center_clicked + + + + + + GtkFrame + frame12 + 4 + + 0 + False + True + + + 0 + GTK_SHADOW_ETCHED_IN + + + GtkVBox + vbox18 + False + 0 + + + GtkButton + button26 + 4 + + 0 + False + True + + True + + clicked + on_update_clicked + + + + + + GtkHBox + hbox13 + + 0 + False + True + + False + 0 + + + GtkCheckButton + update + 4 + + 0 + False + True + + True + + toggled + on_button_toggled + + + False + True + + + + GtkHScale + update_time + + 0 + True + True + + True + True + GTK_POS_RIGHT + 2 + GTK_UPDATE_CONTINUOUS + 0.25 + 0 + 5 + 0 + 0 + 0 + + + + GtkLabel + label34 + + 0 + False + True + + + GTK_JUSTIFY_LEFT + 0 + 0.5 + 0 + 0 + + + + + + + GtkFrame + frame13 + 4 + + 0 + False + True + + + 0 + GTK_SHADOW_ETCHED_IN + + + GtkHBox + hbox14 + 4 + False + 0 + + + GtkButton + button27 + + 0 + True + True + + True + + clicked + on_paint_clicked + + + + + + GtkButton + button28 + + 0 + True + True + + True + + clicked + on_generate_clicked + + + + + + + + + GtkVBox + vbox9 + False + 0 + + + GtkVBox + vbox11 + 4 + + 0 + True + True + + False + 0 + + + GtkFrame + frame9 + 4 + + 0 + False + True + + + 0 + GTK_SHADOW_ETCHED_IN + + + GtkVBox + vbox12 + False + 0 + + + GtkRadioButton + fastest + + 0 + True + True + + True + + toggled + on_button_toggled + + + False + True + perspective + + + + GtkRadioButton + nicest + + 0 + True + True + + True + + toggled + on_button_toggled + + + False + True + perspective + + + + + + GtkFrame + frame10 + 4 + + 0 + False + True + + + 0 + GTK_SHADOW_ETCHED_IN + + + GtkVBox + vbox13 + False + 0 + + + GtkRadioButton + nearest + + 0 + True + True + + True + + toggled + on_button_toggled + + + False + True + filter + + + + GtkRadioButton + linear + + 0 + True + True + + True + + toggled + on_button_toggled + + + False + True + filter + + + + + + + + GtkVBox + vbox14 + 4 + False + 0 + + + GtkLabel + frame_info + + 0 + False + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + frame_info2 + + 0 + False + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkTable + table1 + 4 + + 0 + False + True + + 4 + 2 + False + 0 + 0 + + + GtkHScale + cur_frame + + 1 + 2 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + True + True + GTK_POS_TOP + 0 + GTK_UPDATE_CONTINUOUS + 0 + 0 + 0 + 1 + 10 + 0 + + + + GtkHScale + start_frame + + 1 + 2 + 1 + 2 + 0 + 0 + True + True + False + False + True + True + + True + True + GTK_POS_TOP + 0 + GTK_UPDATE_CONTINUOUS + 0 + 0 + 0 + 1 + 10 + 0 + + + + GtkHScale + end_frame + + 1 + 2 + 2 + 3 + 0 + 0 + True + True + False + False + True + True + + True + True + GTK_POS_TOP + 0 + GTK_UPDATE_CONTINUOUS + 0 + 0 + 0 + 1 + 10 + 0 + + + + GtkLabel + l2 + + 0 + 1 + 1 + 2 + 0 + 0 + False + True + False + False + True + True + + + GTK_JUSTIFY_LEFT + 0 + 1 + 0 + 0 + + + + GtkLabel + l3 + + 0 + 1 + 2 + 3 + 0 + 0 + False + True + False + False + True + True + + + GTK_JUSTIFY_LEFT + 0 + 1 + 0 + 0 + + + + GtkLabel + l1 + + 0 + 1 + 0 + 1 + 0 + 0 + False + True + False + False + True + True + + + GTK_JUSTIFY_LEFT + 0 + 1 + 0 + 0 + + + + GtkLabel + l4 + + 0 + 1 + 3 + 4 + 0 + 0 + False + True + False + False + True + True + + + GTK_JUSTIFY_LEFT + 0 + 1 + 0 + 0 + + + + GtkHScale + fps + + 1 + 2 + 3 + 4 + 0 + 0 + True + True + False + False + True + True + + True + True + GTK_POS_TOP + 1 + GTK_UPDATE_CONTINUOUS + 18 + 0 + 50 + 1 + 4 + 0 + + + + + GtkHBox + anim_hbox + 10 + + 0 + False + True + + False + 0 + + + Placeholder + + + + + + GtkVBox + vbox25 + False + 0 + + + GtkFrame + frame17 + 2 + + 0 + True + True + + + 0.5 + GTK_SHADOW_ETCHED_IN + + + GtkVBox + vbox26 + 2 + False + 0 + + + GtkLabel + version + + 0 + True + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + label779 + + 0 + True + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + label780 + + 0 + True + True + + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + + + + GtkLabel + Notebook:tab + label7 + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + Notebook:tab + label8 + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + Notebook:tab + label9 + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + Notebook:tab + label10 + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + Notebook:tab + label777 + + GTK_JUSTIFY_CENTER + 0.5 + 0.5 + 0 + 0 + + + + + GtkHBox + Dialog:action_area + dialog-action_area2 + 10 + + 0 + False + True + GTK_PACK_END + + True + 5 + + + GtkButton + close + + 0 + True + True + + True + + clicked + on_close_clicked + + + + + + + + diff --git a/tools/texpaint/gladesig.c b/tools/texpaint/gladesig.c new file mode 100644 index 000000000..90b27a187 --- /dev/null +++ b/tools/texpaint/gladesig.c @@ -0,0 +1,189 @@ +/* Note: You are free to use whatever license you want. + Eventually you will be able to edit it within Glade. */ + +/* + * 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. +*/ + +#include +#include "gladesrc.h" +#include "gladesig.h" + +int +main (int argc, char *argv[]) +{ + GtkWidget *glwindow; + GtkWidget *fileselection; + GtkWidget *pakdialog; + GtkWidget *dialog; + + gtk_set_locale (); + gtk_init (&argc, &argv); + + /* + * The following code was added by Glade to create one of each component + * (except popup menus), just so that you see something after building + * the project. Delete any components that you don't want shown initially. + */ + glwindow = create_glwindow (); + gtk_widget_show (glwindow); + fileselection = create_fileselection (); + gtk_widget_show (fileselection); + pakdialog = create_pakdialog (); + gtk_widget_show (pakdialog); + dialog = create_dialog (); + gtk_widget_show (dialog); + + gtk_main (); + return 0; +} + +void +on_glwindow_destroy (GtkObject *object, + gpointer user_data) +{ + +} + +gboolean +on_fileselection_delete (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + + return FALSE; +} + +void +on_ok_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_cancel_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_dialog_destroy (GtkObject *object, + gpointer user_data) +{ + +} + +void +on_load_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_images_menu_enter (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_scale_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_base_texture_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_center_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_update_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + +void +on_paint_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_generate_clicked (GtkButton *button, + gpointer user_data) +{ + +} + +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + +} + +void +on_close_clicked (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/tools/texpaint/gladesig.h b/tools/texpaint/gladesig.h new file mode 100644 index 000000000..32d00ae35 --- /dev/null +++ b/tools/texpaint/gladesig.h @@ -0,0 +1,79 @@ +/* Note: You are free to use whatever license you want. + Eventually you will be able to edit it within Glade. */ + +/* + * 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. +*/ + +void +on_glwindow_destroy (GtkObject *object, + gpointer user_data); +gboolean +on_fileselection_delete (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); +void +on_ok_clicked (GtkButton *button, + gpointer user_data); +void +on_cancel_clicked (GtkButton *button, + gpointer user_data); +void +on_dialog_destroy (GtkObject *object, + gpointer user_data); +void +on_load_clicked (GtkButton *button, + gpointer user_data); +void +on_images_menu_enter (GtkButton *button, + gpointer user_data); +void +on_scale_clicked (GtkButton *button, + gpointer user_data); +void +on_base_texture_clicked (GtkButton *button, + gpointer user_data); +void +on_center_clicked (GtkButton *button, + gpointer user_data); +void +on_update_clicked (GtkButton *button, + gpointer user_data); +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); +void +on_paint_clicked (GtkButton *button, + gpointer user_data); +void +on_generate_clicked (GtkButton *button, + gpointer user_data); +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); +void +on_button_toggled (GtkToggleButton *togglebutton, + gpointer user_data); +void +on_close_clicked (GtkButton *button, + gpointer user_data); diff --git a/tools/texpaint/gladesrc.c b/tools/texpaint/gladesrc.c new file mode 100644 index 000000000..6d9e65229 --- /dev/null +++ b/tools/texpaint/gladesrc.c @@ -0,0 +1,706 @@ +/* Note: You are free to use whatever license you want. + Eventually you will be able to edit it within Glade. */ + +/* + * 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. +*/ + +#include +#include +#include "gladesig.h" +#include "gladesrc.h" + +GtkWidget* +get_widget (GtkWidget *widget, + gchar *widget_name) +{ + GtkWidget *found_widget; + + if (widget->parent) + widget = gtk_widget_get_toplevel (widget); + found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +/* This is an internally used function to set notebook tab widgets. */ +void +set_notebook_tab (GtkWidget *notebook, + gint page_num, + GtkWidget *widget) +{ + GtkNotebookPage *page; + GtkWidget *notebook_page; + + page = (GtkNotebookPage*) g_list_nth (GTK_NOTEBOOK (notebook)->children, page_num)->data; + notebook_page = page->child; + gtk_widget_ref (notebook_page); + gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), page_num); + gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), notebook_page, + widget, page_num); + gtk_widget_unref (notebook_page); +} + +GtkWidget* +create_glwindow () +{ + GtkWidget *glwindow; + + glwindow = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_object_set_data (GTK_OBJECT (glwindow), "glwindow", glwindow); + gtk_signal_connect (GTK_OBJECT (glwindow), "destroy", + GTK_SIGNAL_FUNC (on_glwindow_destroy), + NULL); + gtk_window_set_title (GTK_WINDOW (glwindow), "3D Window"); + gtk_window_set_policy (GTK_WINDOW (glwindow), TRUE, TRUE, FALSE); + + return glwindow; +} + +GtkWidget* +create_fileselection () +{ + GtkWidget *fileselection; + GtkWidget *ok_button1; + GtkWidget *cancel_button1; + + fileselection = gtk_file_selection_new ("Select a PAK, MDL or MD2 file"); + gtk_object_set_data (GTK_OBJECT (fileselection), "fileselection", fileselection); + gtk_container_border_width (GTK_CONTAINER (fileselection), 10); + gtk_signal_connect (GTK_OBJECT (fileselection), "delete_event", + GTK_SIGNAL_FUNC (on_fileselection_delete), + NULL); + + ok_button1 = GTK_FILE_SELECTION (fileselection)->ok_button; + gtk_object_set_data (GTK_OBJECT (fileselection), "ok_button1", ok_button1); + gtk_widget_show (ok_button1); + GTK_WIDGET_SET_FLAGS (ok_button1, GTK_CAN_DEFAULT); + gtk_signal_connect (GTK_OBJECT (ok_button1), "clicked", + GTK_SIGNAL_FUNC (on_ok_clicked), + NULL); + + cancel_button1 = GTK_FILE_SELECTION (fileselection)->cancel_button; + gtk_object_set_data (GTK_OBJECT (fileselection), "cancel_button1", cancel_button1); + gtk_widget_show (cancel_button1); + GTK_WIDGET_SET_FLAGS (cancel_button1, GTK_CAN_DEFAULT); + gtk_signal_connect (GTK_OBJECT (cancel_button1), "clicked", + GTK_SIGNAL_FUNC (on_cancel_clicked), + NULL); + + return fileselection; +} + +GtkWidget* +create_pakdialog () +{ + GtkWidget *pakdialog; + GtkWidget *vbox8; + GtkWidget *filename; + GtkWidget *scrolledwindow; + GtkWidget *open; + GtkWidget *close; + + pakdialog = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_object_set_data (GTK_OBJECT (pakdialog), "pakdialog", pakdialog); + gtk_widget_set_usize (pakdialog, 256, 256); + gtk_container_border_width (GTK_CONTAINER (pakdialog), 4); + gtk_window_set_title (GTK_WINDOW (pakdialog), "Select a MDL, MD2 or PCX file"); + gtk_window_set_policy (GTK_WINDOW (pakdialog), TRUE, TRUE, FALSE); + + vbox8 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (pakdialog), "vbox8", vbox8); + gtk_widget_show (vbox8); + gtk_container_add (GTK_CONTAINER (pakdialog), vbox8); + + filename = gtk_label_new ("filename"); + gtk_object_set_data (GTK_OBJECT (pakdialog), "filename", filename); + gtk_widget_show (filename); + gtk_box_pack_start (GTK_BOX (vbox8), filename, FALSE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (filename), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (filename), 0, 0.5); + + scrolledwindow = gtk_scrolled_window_new (NULL, NULL); + gtk_object_set_data (GTK_OBJECT (pakdialog), "scrolledwindow", scrolledwindow); + gtk_widget_show (scrolledwindow); + gtk_box_pack_start (GTK_BOX (vbox8), scrolledwindow, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (scrolledwindow), 4); + + open = gtk_button_new_with_label ("Open"); + gtk_object_set_data (GTK_OBJECT (pakdialog), "open", open); + gtk_widget_show (open); + gtk_box_pack_start (GTK_BOX (vbox8), open, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (open), 4); + + close = gtk_button_new_with_label ("Close"); + gtk_object_set_data (GTK_OBJECT (pakdialog), "close", close); + gtk_widget_show (close); + gtk_box_pack_start (GTK_BOX (vbox8), close, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (close), 4); + + return pakdialog; +} + +GtkWidget* +create_dialog () +{ + GtkWidget *dialog; + GtkWidget *dialog_vbox2; + GtkWidget *hbox7; + GtkWidget *label14; + GtkWidget *models_menu; + GtkWidget *models_menu_menu; + GtkWidget *glade_menuitem; + GtkWidget *notebook1; + GtkWidget *vbox15; + GtkWidget *button19; + GtkWidget *frame11; + GtkWidget *vbox17; + GtkWidget *hbox11; + GtkWidget *label30; + GtkWidget *images_menu; + GtkWidget *images_menu_menu; + GtkWidget *info; + GtkWidget *table4; + GtkObject *height_adj; + GtkWidget *height; + GtkObject *width_adj; + GtkWidget *width; + GtkWidget *l30; + GtkWidget *l20; + GtkWidget *new_image; + GtkWidget *scale; + GtkWidget *base_texture; + GtkWidget *vbox16; + GtkWidget *button21; + GtkWidget *frame12; + GtkWidget *vbox18; + GtkWidget *button26; + GtkWidget *hbox13; + GtkWidget *update; + GtkWidget *update_time; + GtkWidget *label34; + GtkWidget *frame13; + GtkWidget *hbox14; + GtkWidget *button27; + GtkWidget *button28; + GtkWidget *vbox9; + GtkWidget *vbox11; + GtkWidget *frame9; + GtkWidget *vbox12; + GSList *perspective_group = NULL; + GtkWidget *fastest; + GtkWidget *nicest; + GtkWidget *frame10; + GtkWidget *vbox13; + GSList *filter_group = NULL; + GtkWidget *nearest; + GtkWidget *linear; + GtkWidget *vbox14; + GtkWidget *frame_info; + GtkWidget *frame_info2; + GtkWidget *table1; + GtkWidget *fps; + GtkWidget *l4; + GtkWidget *l1; + GtkWidget *l3; + GtkWidget *l2; + GtkWidget *end_frame; + GtkWidget *start_frame; + GtkWidget *cur_frame; + GtkWidget *anim_hbox; + GtkWidget *vbox25; + GtkWidget *frame17; + GtkWidget *vbox26; + GtkWidget *version; + GtkWidget *label779; + GtkWidget *label780; + GtkWidget *label7; + GtkWidget *label8; + GtkWidget *label9; + GtkWidget *label10; + GtkWidget *label777; + GtkWidget *dialog_action_area2; + GtkWidget *close; + + dialog = gtk_dialog_new (); + gtk_object_set_data (GTK_OBJECT (dialog), "dialog", dialog); + gtk_container_border_width (GTK_CONTAINER (dialog), 2); + gtk_signal_connect (GTK_OBJECT (dialog), "destroy", + GTK_SIGNAL_FUNC (on_dialog_destroy), + NULL); + gtk_window_set_title (GTK_WINDOW (dialog), "Texture Paint"); + gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, TRUE, FALSE); + + dialog_vbox2 = GTK_DIALOG (dialog)->vbox; + gtk_object_set_data (GTK_OBJECT (dialog), "dialog_vbox2", dialog_vbox2); + gtk_widget_show (dialog_vbox2); + + hbox7 = gtk_hbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "hbox7", hbox7); + gtk_widget_show (hbox7); + gtk_box_pack_start (GTK_BOX (dialog_vbox2), hbox7, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (hbox7), 4); + + label14 = gtk_label_new ("Model:"); + gtk_object_set_data (GTK_OBJECT (dialog), "label14", label14); + gtk_widget_show (label14); + gtk_box_pack_start (GTK_BOX (hbox7), label14, FALSE, TRUE, 0); + + models_menu = gtk_option_menu_new (); + gtk_object_set_data (GTK_OBJECT (dialog), "models_menu", models_menu); + gtk_widget_show (models_menu); + gtk_box_pack_start (GTK_BOX (hbox7), models_menu, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (models_menu), 4); + models_menu_menu = gtk_menu_new (); + gtk_option_menu_set_menu (GTK_OPTION_MENU (models_menu), models_menu_menu); + + notebook1 = gtk_notebook_new (); + gtk_object_set_data (GTK_OBJECT (dialog), "notebook1", notebook1); + gtk_widget_show (notebook1); + gtk_box_pack_start (GTK_BOX (dialog_vbox2), notebook1, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (notebook1), 4); + + vbox15 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox15", vbox15); + gtk_widget_show (vbox15); + gtk_container_add (GTK_CONTAINER (notebook1), vbox15); + + button19 = gtk_button_new_with_label ("Load Model / PAK / Image"); + gtk_object_set_data (GTK_OBJECT (dialog), "button19", button19); + gtk_widget_show (button19); + gtk_box_pack_start (GTK_BOX (vbox15), button19, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (button19), 4); + gtk_signal_connect (GTK_OBJECT (button19), "clicked", + GTK_SIGNAL_FUNC (on_load_clicked), + NULL); + + frame11 = gtk_frame_new ("Texture"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame11", frame11); + gtk_widget_show (frame11); + gtk_box_pack_start (GTK_BOX (vbox15), frame11, TRUE, TRUE, 0); + + vbox17 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox17", vbox17); + gtk_widget_show (vbox17); + gtk_container_add (GTK_CONTAINER (frame11), vbox17); + + hbox11 = gtk_hbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "hbox11", hbox11); + gtk_widget_show (hbox11); + gtk_box_pack_start (GTK_BOX (vbox17), hbox11, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (hbox11), 4); + + label30 = gtk_label_new ("Image: "); + gtk_object_set_data (GTK_OBJECT (dialog), "label30", label30); + gtk_widget_show (label30); + gtk_box_pack_start (GTK_BOX (hbox11), label30, FALSE, TRUE, 0); + + images_menu = gtk_option_menu_new (); + gtk_object_set_data (GTK_OBJECT (dialog), "images_menu", images_menu); + gtk_widget_show (images_menu); + gtk_box_pack_start (GTK_BOX (hbox11), images_menu, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (images_menu), 2); + gtk_signal_connect (GTK_OBJECT (images_menu), "enter", + GTK_SIGNAL_FUNC (on_images_menu_enter), + NULL); + images_menu_menu = gtk_menu_new (); + gtk_option_menu_set_menu (GTK_OPTION_MENU (images_menu), images_menu_menu); + + info = gtk_label_new ("info"); + gtk_object_set_data (GTK_OBJECT (dialog), "info", info); + gtk_widget_show (info); + gtk_box_pack_start (GTK_BOX (vbox17), info, FALSE, TRUE, 0); + + table4 = gtk_table_new (2, 2, FALSE); + gtk_object_set_data (GTK_OBJECT (dialog), "table4", table4); + gtk_widget_show (table4); + gtk_box_pack_start (GTK_BOX (vbox17), table4, FALSE, TRUE, 0); + + height_adj = gtk_adjustment_new (1, 1, 5000, 1, 10, 10); + height = gtk_spin_button_new (GTK_ADJUSTMENT (height_adj), 1, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "height", height); + gtk_widget_show (height); + gtk_table_attach (GTK_TABLE (table4), height, 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + width_adj = gtk_adjustment_new (1, 1, 5000, 1, 10, 10); + width = gtk_spin_button_new (GTK_ADJUSTMENT (width_adj), 1, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "width", width); + gtk_widget_show (width); + gtk_table_attach (GTK_TABLE (table4), width, 1, 2, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + l30 = gtk_label_new ("New Height:"); + gtk_object_set_data (GTK_OBJECT (dialog), "l30", l30); + gtk_widget_show (l30); + gtk_table_attach (GTK_TABLE (table4), l30, 0, 1, 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_label_set_justify (GTK_LABEL (l30), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (l30), 0, 0.5); + + l20 = gtk_label_new ("New Width:"); + gtk_object_set_data (GTK_OBJECT (dialog), "l20", l20); + gtk_widget_show (l20); + gtk_table_attach (GTK_TABLE (table4), l20, 0, 1, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_label_set_justify (GTK_LABEL (l20), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (l20), 0, 0.5); + + new_image = gtk_check_button_new_with_label ("Create new Image"); + gtk_object_set_data (GTK_OBJECT (dialog), "new_image", new_image); + gtk_widget_show (new_image); + gtk_box_pack_start (GTK_BOX (vbox17), new_image, FALSE, TRUE, 0); + + scale = gtk_button_new_with_label ("Scale / Convert RGB"); + gtk_object_set_data (GTK_OBJECT (dialog), "scale", scale); + gtk_widget_show (scale); + gtk_box_pack_start (GTK_BOX (vbox17), scale, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (scale), "clicked", + GTK_SIGNAL_FUNC (on_scale_clicked), + NULL); + + base_texture = gtk_button_new_with_label ("Base Texture"); + gtk_object_set_data (GTK_OBJECT (dialog), "base_texture", base_texture); + gtk_widget_show (base_texture); + gtk_box_pack_start (GTK_BOX (vbox17), base_texture, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (base_texture), "clicked", + GTK_SIGNAL_FUNC (on_base_texture_clicked), + NULL); + + vbox16 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox16", vbox16); + gtk_widget_show (vbox16); + gtk_container_add (GTK_CONTAINER (notebook1), vbox16); + gtk_container_border_width (GTK_CONTAINER (vbox16), 4); + + button21 = gtk_button_new_with_label ("Center Model"); + gtk_object_set_data (GTK_OBJECT (dialog), "button21", button21); + gtk_widget_show (button21); + gtk_box_pack_start (GTK_BOX (vbox16), button21, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (button21), 4); + gtk_signal_connect (GTK_OBJECT (button21), "clicked", + GTK_SIGNAL_FUNC (on_center_clicked), + NULL); + + frame12 = gtk_frame_new ("Texture Paint"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame12", frame12); + gtk_widget_show (frame12); + gtk_box_pack_start (GTK_BOX (vbox16), frame12, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (frame12), 4); + + vbox18 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox18", vbox18); + gtk_widget_show (vbox18); + gtk_container_add (GTK_CONTAINER (frame12), vbox18); + + button26 = gtk_button_new_with_label ("Update"); + gtk_object_set_data (GTK_OBJECT (dialog), "button26", button26); + gtk_widget_show (button26); + gtk_box_pack_start (GTK_BOX (vbox18), button26, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (button26), 4); + gtk_signal_connect (GTK_OBJECT (button26), "clicked", + GTK_SIGNAL_FUNC (on_update_clicked), + NULL); + + hbox13 = gtk_hbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "hbox13", hbox13); + gtk_widget_show (hbox13); + gtk_box_pack_start (GTK_BOX (vbox18), hbox13, FALSE, TRUE, 0); + + update = gtk_check_button_new_with_label ("Update after"); + gtk_object_set_data (GTK_OBJECT (dialog), "update", update); + gtk_widget_show (update); + gtk_box_pack_start (GTK_BOX (hbox13), update, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (update), 4); + gtk_signal_connect (GTK_OBJECT (update), "toggled", + GTK_SIGNAL_FUNC (on_button_toggled), + NULL); + + update_time = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0.25, 0, 5, 0, 0, 0))); + gtk_object_set_data (GTK_OBJECT (dialog), "update_time", update_time); + gtk_widget_show (update_time); + gtk_box_pack_start (GTK_BOX (hbox13), update_time, TRUE, TRUE, 0); + gtk_scale_set_value_pos (GTK_SCALE (update_time), GTK_POS_RIGHT); + gtk_scale_set_digits (GTK_SCALE (update_time), 2); + + label34 = gtk_label_new (" seconds."); + gtk_object_set_data (GTK_OBJECT (dialog), "label34", label34); + gtk_widget_show (label34); + gtk_box_pack_start (GTK_BOX (hbox13), label34, FALSE, TRUE, 0); + gtk_label_set_justify (GTK_LABEL (label34), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); + + frame13 = gtk_frame_new ("3D Paint"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame13", frame13); + gtk_widget_show (frame13); + gtk_box_pack_start (GTK_BOX (vbox16), frame13, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (frame13), 4); + + hbox14 = gtk_hbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "hbox14", hbox14); + gtk_widget_show (hbox14); + gtk_container_add (GTK_CONTAINER (frame13), hbox14); + gtk_container_border_width (GTK_CONTAINER (hbox14), 4); + + button27 = gtk_button_new_with_label ("Open 3D Paint Window"); + gtk_object_set_data (GTK_OBJECT (dialog), "button27", button27); + gtk_widget_show (button27); + gtk_box_pack_start (GTK_BOX (hbox14), button27, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (button27), "clicked", + GTK_SIGNAL_FUNC (on_paint_clicked), + NULL); + + button28 = gtk_button_new_with_label ("Calculate Texture"); + gtk_object_set_data (GTK_OBJECT (dialog), "button28", button28); + gtk_widget_show (button28); + gtk_box_pack_start (GTK_BOX (hbox14), button28, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (button28), "clicked", + GTK_SIGNAL_FUNC (on_generate_clicked), + NULL); + + vbox9 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox9", vbox9); + gtk_widget_show (vbox9); + gtk_container_add (GTK_CONTAINER (notebook1), vbox9); + + vbox11 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox11", vbox11); + gtk_widget_show (vbox11); + gtk_box_pack_start (GTK_BOX (vbox9), vbox11, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (vbox11), 4); + + frame9 = gtk_frame_new ("Perspective correction"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame9", frame9); + gtk_widget_show (frame9); + gtk_box_pack_start (GTK_BOX (vbox11), frame9, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (frame9), 4); + + vbox12 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox12", vbox12); + gtk_widget_show (vbox12); + gtk_container_add (GTK_CONTAINER (frame9), vbox12); + + fastest = gtk_radio_button_new_with_label (perspective_group, "fastest"); + perspective_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fastest)); + gtk_object_set_data (GTK_OBJECT (dialog), "fastest", fastest); + gtk_widget_show (fastest); + gtk_box_pack_start (GTK_BOX (vbox12), fastest, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (fastest), "toggled", + GTK_SIGNAL_FUNC (on_button_toggled), + NULL); + + nicest = gtk_radio_button_new_with_label (perspective_group, "nicest"); + perspective_group = gtk_radio_button_group (GTK_RADIO_BUTTON (nicest)); + gtk_object_set_data (GTK_OBJECT (dialog), "nicest", nicest); + gtk_widget_show (nicest); + gtk_box_pack_start (GTK_BOX (vbox12), nicest, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (nicest), "toggled", + GTK_SIGNAL_FUNC (on_button_toggled), + NULL); + + frame10 = gtk_frame_new ("Texture filter"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame10", frame10); + gtk_widget_show (frame10); + gtk_box_pack_start (GTK_BOX (vbox11), frame10, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (frame10), 4); + + vbox13 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox13", vbox13); + gtk_widget_show (vbox13); + gtk_container_add (GTK_CONTAINER (frame10), vbox13); + + nearest = gtk_radio_button_new_with_label (filter_group, "nearest"); + filter_group = gtk_radio_button_group (GTK_RADIO_BUTTON (nearest)); + gtk_object_set_data (GTK_OBJECT (dialog), "nearest", nearest); + gtk_widget_show (nearest); + gtk_box_pack_start (GTK_BOX (vbox13), nearest, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (nearest), "toggled", + GTK_SIGNAL_FUNC (on_button_toggled), + NULL); + + linear = gtk_radio_button_new_with_label (filter_group, "linear"); + filter_group = gtk_radio_button_group (GTK_RADIO_BUTTON (linear)); + gtk_object_set_data (GTK_OBJECT (dialog), "linear", linear); + gtk_widget_show (linear); + gtk_box_pack_start (GTK_BOX (vbox13), linear, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (linear), "toggled", + GTK_SIGNAL_FUNC (on_button_toggled), + NULL); + + vbox14 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox14", vbox14); + gtk_widget_show (vbox14); + gtk_container_add (GTK_CONTAINER (notebook1), vbox14); + gtk_container_border_width (GTK_CONTAINER (vbox14), 4); + + frame_info = gtk_label_new ("Info"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame_info", frame_info); + gtk_widget_show (frame_info); + gtk_box_pack_start (GTK_BOX (vbox14), frame_info, FALSE, TRUE, 0); + + frame_info2 = gtk_label_new ("frame 123"); + gtk_object_set_data (GTK_OBJECT (dialog), "frame_info2", frame_info2); + gtk_widget_show (frame_info2); + gtk_box_pack_start (GTK_BOX (vbox14), frame_info2, FALSE, TRUE, 0); + + table1 = gtk_table_new (4, 2, FALSE); + gtk_object_set_data (GTK_OBJECT (dialog), "table1", table1); + gtk_widget_show (table1); + gtk_box_pack_start (GTK_BOX (vbox14), table1, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (table1), 4); + + fps = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (18, 0, 50, 1, 4, 0))); + gtk_object_set_data (GTK_OBJECT (dialog), "fps", fps); + gtk_widget_show (fps); + gtk_table_attach (GTK_TABLE (table1), fps, 1, 2, 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + l4 = gtk_label_new ("Frames per second "); + gtk_object_set_data (GTK_OBJECT (dialog), "l4", l4); + gtk_widget_show (l4); + gtk_table_attach (GTK_TABLE (table1), l4, 0, 1, 3, 4, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_label_set_justify (GTK_LABEL (l4), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (l4), 0, 1); + + l1 = gtk_label_new ("Current Frame "); + gtk_object_set_data (GTK_OBJECT (dialog), "l1", l1); + gtk_widget_show (l1); + gtk_table_attach (GTK_TABLE (table1), l1, 0, 1, 0, 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_label_set_justify (GTK_LABEL (l1), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (l1), 0, 1); + + l3 = gtk_label_new ("End Frame"); + gtk_object_set_data (GTK_OBJECT (dialog), "l3", l3); + gtk_widget_show (l3); + gtk_table_attach (GTK_TABLE (table1), l3, 0, 1, 2, 3, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_label_set_justify (GTK_LABEL (l3), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (l3), 0, 1); + + l2 = gtk_label_new ("Start Frame"); + gtk_object_set_data (GTK_OBJECT (dialog), "l2", l2); + gtk_widget_show (l2); + gtk_table_attach (GTK_TABLE (table1), l2, 0, 1, 1, 2, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_label_set_justify (GTK_LABEL (l2), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (l2), 0, 1); + + end_frame = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 1, 10, 0))); + gtk_object_set_data (GTK_OBJECT (dialog), "end_frame", end_frame); + gtk_widget_show (end_frame); + gtk_table_attach (GTK_TABLE (table1), end_frame, 1, 2, 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_scale_set_digits (GTK_SCALE (end_frame), 0); + + start_frame = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 1, 10, 0))); + gtk_object_set_data (GTK_OBJECT (dialog), "start_frame", start_frame); + gtk_widget_show (start_frame); + gtk_table_attach (GTK_TABLE (table1), start_frame, 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_scale_set_digits (GTK_SCALE (start_frame), 0); + + cur_frame = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 1, 10, 0))); + gtk_object_set_data (GTK_OBJECT (dialog), "cur_frame", cur_frame); + gtk_widget_show (cur_frame); + gtk_table_attach (GTK_TABLE (table1), cur_frame, 1, 2, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_scale_set_digits (GTK_SCALE (cur_frame), 0); + + anim_hbox = gtk_hbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "anim_hbox", anim_hbox); + gtk_widget_show (anim_hbox); + gtk_box_pack_start (GTK_BOX (vbox14), anim_hbox, FALSE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (anim_hbox), 10); + + vbox25 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox25", vbox25); + gtk_widget_show (vbox25); + gtk_container_add (GTK_CONTAINER (notebook1), vbox25); + + frame17 = gtk_frame_new (""); + gtk_object_set_data (GTK_OBJECT (dialog), "frame17", frame17); + gtk_widget_show (frame17); + gtk_box_pack_start (GTK_BOX (vbox25), frame17, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (frame17), 2); + gtk_frame_set_label_align (GTK_FRAME (frame17), 0.5, 0.5); + + vbox26 = gtk_vbox_new (FALSE, 0); + gtk_object_set_data (GTK_OBJECT (dialog), "vbox26", vbox26); + gtk_widget_show (vbox26); + gtk_container_add (GTK_CONTAINER (frame17), vbox26); + gtk_container_border_width (GTK_CONTAINER (vbox26), 2); + + version = gtk_label_new ("Texture Paint ???"); + gtk_object_set_data (GTK_OBJECT (dialog), "version", version); + gtk_widget_show (version); + gtk_box_pack_start (GTK_BOX (vbox26), version, TRUE, TRUE, 0); + + label779 = gtk_label_new ("Uwe Maurer "); + gtk_object_set_data (GTK_OBJECT (dialog), "label779", label779); + gtk_widget_show (label779); + gtk_box_pack_start (GTK_BOX (vbox26), label779, TRUE, TRUE, 0); + + label780 = gtk_label_new ("http://home.t-online.de/home/uwe_maurer/texpaint.htm"); + gtk_object_set_data (GTK_OBJECT (dialog), "label780", label780); + gtk_widget_show (label780); + gtk_box_pack_start (GTK_BOX (vbox26), label780, TRUE, TRUE, 0); + + label7 = gtk_label_new ("File"); + gtk_object_set_data (GTK_OBJECT (dialog), "label7", label7); + gtk_widget_show (label7); + set_notebook_tab (notebook1, 0, label7); + + label8 = gtk_label_new ("Paint"); + gtk_object_set_data (GTK_OBJECT (dialog), "label8", label8); + gtk_widget_show (label8); + set_notebook_tab (notebook1, 1, label8); + + label9 = gtk_label_new ("Options"); + gtk_object_set_data (GTK_OBJECT (dialog), "label9", label9); + gtk_widget_show (label9); + set_notebook_tab (notebook1, 2, label9); + + label10 = gtk_label_new ("Animation"); + gtk_object_set_data (GTK_OBJECT (dialog), "label10", label10); + gtk_widget_show (label10); + set_notebook_tab (notebook1, 3, label10); + + label777 = gtk_label_new ("About"); + gtk_object_set_data (GTK_OBJECT (dialog), "label777", label777); + gtk_widget_show (label777); + set_notebook_tab (notebook1, 4, label777); + + dialog_action_area2 = GTK_DIALOG (dialog)->action_area; + gtk_object_set_data (GTK_OBJECT (dialog), "dialog_action_area2", dialog_action_area2); + gtk_widget_show (dialog_action_area2); + gtk_container_border_width (GTK_CONTAINER (dialog_action_area2), 10); + + close = gtk_button_new_with_label ("Close"); + gtk_object_set_data (GTK_OBJECT (dialog), "close", close); + gtk_widget_show (close); + gtk_box_pack_start (GTK_BOX (dialog_action_area2), close, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (close), "clicked", + GTK_SIGNAL_FUNC (on_close_clicked), + NULL); + + return dialog; +} + diff --git a/tools/texpaint/gladesrc.h b/tools/texpaint/gladesrc.h new file mode 100644 index 000000000..cdfe75b85 --- /dev/null +++ b/tools/texpaint/gladesrc.h @@ -0,0 +1,45 @@ +/* Note: You are free to use whatever license you want. + Eventually you will be able to edit it within Glade. */ + +/* + * 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. +*/ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* +get_widget (GtkWidget *widget, + gchar *widget_name); + + + /* + * This is an internally used function for setting notebook tabs. It is only + * included in this header file so you don't get compilation warnings + */ +void +set_notebook_tab (GtkWidget *notebook, + gint page_num, + GtkWidget *widget); + +GtkWidget* create_glwindow (void); +GtkWidget* create_fileselection (void); +GtkWidget* create_pakdialog (void); +GtkWidget* create_dialog (void); diff --git a/tools/texpaint/main.c b/tools/texpaint/main.c new file mode 100644 index 000000000..5a8b241f2 --- /dev/null +++ b/tools/texpaint/main.c @@ -0,0 +1,423 @@ +/* Texture Paint + * Plug-in for the GIMP + * + * Copyright (C) 1998 Uwe Maurer + * + * Based on GiMd2Viewer-0.1 (Quake2 model viewer) by + * Copyright (C) 1998 Lionel ULMER + * Copyright (C) 1997-1998 Janne Löf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "texturepaint.h" + + +void begingl(GtkWidget *glarea) +{ + if (!gtk_gl_area_begingl(GTK_GL_AREA(glarea))) + { + gimp_message("gtk_gl_area_begingl failed()!"); + gtk_main_quit(); + } +} + +void endgl(GtkWidget *glarea) +{ + gtk_gl_area_endgl(GTK_GL_AREA(glarea)); +} + +gint expose(GtkWidget *widget, GdkEventExpose *event, gpointer data) +{ + model_draw((ModelInfo*)data); + return TRUE; +} + +gint resize(GtkWidget *widget, GdkEventConfigure *event,gpointer data) +{ + if (!GTK_WIDGET_REALIZED(widget)) + return TRUE; + + begingl(widget); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, + (float) widget->allocation.width / widget->allocation.height, + 0.1, 200.0); + glMatrixMode(GL_MODELVIEW); + + glViewport(0, 0, widget->allocation.width, widget->allocation.height); + + model_draw((ModelInfo *)data); + + endgl(widget); + + return TRUE; +} + + +void BindTexture(ModelInfo *mdl,char *texdata,int w,int h) +{ + + DEBUG("%s %i",mdl->name,mdl->tex_image); + + glBindTexture(GL_TEXTURE_2D, mdl->texture); + set_parameter(mdl); + + glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, + GL_RGB, GL_UNSIGNED_BYTE, texdata); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + glBindTexture(GL_TEXTURE_2D,mdl->texture); +} + + +gint button_press_event(GtkWidget *widget, GdkEventButton *event,gpointer data) +{ + ModelInfo *mdl; + + mdl=(ModelInfo *)data; + + if (event->type==GDK_2BUTTON_PRESS) + { + if (event->button==1) + on_paint_clicked(NULL,mdl); + else if (event->button==3) + on_generate_clicked(NULL,mdl); + + } + + if (event->button == 1) + { + mdl->M1_beginx = event->x; + mdl->M1_beginy = event->y; + trackball(mdl->lastquat,0,0,0,0); + } else if (event->button == 2) + { + mdl->M2_beginx = event->x; + mdl->M2_beginy = event->y; + } else if (event->button == 3) + { + mdl->M3_beginy = event->y; + } + return TRUE; +} + +gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event, + gpointer data) +{ + int x, y; + int width,height; + GdkModifierType state; + ModelInfo *mdl; + + + mdl=(ModelInfo *)data; + + width=widget->allocation.width; + height=widget->allocation.height; + + if (event->is_hint) + { + gdk_window_get_pointer(event->window, &x, &y, &state); + } else + { + x=event->x; + y=event->y; + state = event->state; + } + + if ((state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK))==0) + return TRUE; + + + if (state & GDK_BUTTON1_MASK) + { + trackball(mdl->lastquat, + (2.0 * mdl->M1_beginx - width) / width, + (height- 2.0 * mdl->M1_beginy) / height, + (2.0 * x - width) / width, + (height- 2.0 * y) / height); + mdl->M1_beginx = x; + mdl->M1_beginy = y; + add_quats(mdl->lastquat,mdl->curquat,mdl->curquat); + } else if (state & GDK_BUTTON2_MASK) + { + mdl->obj_Xpos += (mdl->obj_Zpos / -width) * (x - mdl->M2_beginx); + mdl->obj_Ypos -= (mdl->obj_Zpos / -height) * (y - mdl->M2_beginy); + + mdl->M2_beginx = x; + mdl->M2_beginy = y; + + } else if (state & GDK_BUTTON3_MASK) + { + mdl->obj_Zpos += (mdl->obj_Zpos / -height) * (y - mdl->M3_beginy); + mdl->M3_beginy = y; + } + + model_draw(mdl); + + return TRUE; +} + +static void initgl(ModelInfo *mdl) +{ + static int first_initgl=1; + GtkWidget *widget; + GLint data[4]; + + widget=mdl->glarea; + + if (first_initgl) + { + glGetIntegerv(GL_MAX_TEXTURE_SIZE,data); + max_tex_size=data[0]; + + glGetIntegerv(GL_RED_BITS,data); + red_bits=data[0]; + glGetIntegerv(GL_GREEN_BITS,data); + green_bits=data[0]; + glGetIntegerv(GL_BLUE_BITS,data); + blue_bits=data[0]; + + red_shift = 8-red_bits; + green_shift = 8-green_bits; + blue_shift = 8-blue_bits; + + first_initgl=0; + } + + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, + (float) widget->allocation.width / widget->allocation.height, + 0.1, 200.0); + glMatrixMode(GL_MODELVIEW); + + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glEnable(GL_DEPTH_TEST); + + glDisable(GL_DITHER); + glShadeModel(GL_FLAT); + glEnable(GL_TEXTURE_2D); + + glGenTextures(1,&mdl->texture); + + get_texture(mdl); + + glViewport(0, 0, widget->allocation.width, widget->allocation.height); +} + + +void on_center_clicked(GtkButton *button, gpointer data) +{ + ModelInfo *mdl; + + if (data) + mdl=(ModelInfo *)data; + else + mdl=dialog->mdl; + + if (mdl) + { + mdl->obj_Xpos = 0.0; + mdl->obj_Ypos = 0.0; + mdl->obj_Zpos = -2.0; + trackball(mdl->curquat,0,0,0,0); + trackball(mdl->lastquat,0,0,0,0); + model_draw(mdl); + } +} + +void model_new(char *name,Model *model) +{ + int attrList[]= + { GDK_GL_RGBA, GDK_GL_DOUBLEBUFFER, GDK_GL_DEPTH_SIZE, 1, GDK_GL_NONE}; + + GtkWidget *glarea; + ModelInfo *mdl_info; + char str[256]; + + mdl_info=g_malloc(sizeof(ModelInfo)); + memset(mdl_info,0,sizeof(ModelInfo)); + + mdl_info->name=strdup(name); + mdl_info->model=model; + + mdl_info->tex_image=-1; + mdl_info->paint_image=-1; + mdl_info->idle=-1; + + trackball(mdl_info->curquat,0,0,0,0); + trackball(mdl_info->lastquat,0,0,0,0); + + mdl_info->obj_Zpos=-2; + + mdl_info->first=0; + mdl_info->last=mdl_info->model->numframes-1; + mdl_info->frame=0; + mdl_info->timer=g_timer_new(); + + + mdl_info->glwindow=create_glwindow(); + + strcpy(str,"3D Window - "); + strncat(str,name,200); + gtk_window_set_title(GTK_WINDOW(mdl_info->glwindow),str); + gtk_object_set_data(GTK_OBJECT(mdl_info->glwindow),MODEL_KEY,mdl_info); + + glarea = gtk_gl_area_new(attrList); + mdl_info->glarea=glarea; + + if (glarea == NULL) { + g_print("Can't create GtkGLArea widget\n"); + gtk_exit(1); + } + gtk_widget_set_usize(glarea, 200, 200); /* Minimum size */ + gtk_widget_set_events(glarea, + GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); + + gtk_signal_connect(GTK_OBJECT(glarea), "expose_event", + GTK_SIGNAL_FUNC(expose), mdl_info); + + /* when widgets size changes we want to change glViewport size to match it */ + gtk_signal_connect(GTK_OBJECT(glarea), "configure_event", + GTK_SIGNAL_FUNC(resize), mdl_info); + /* virtual trackball */ + gtk_signal_connect(GTK_OBJECT(glarea), "motion_notify_event", + GTK_SIGNAL_FUNC(motion_notify_event), mdl_info); + gtk_signal_connect(GTK_OBJECT(glarea), "button_press_event", + GTK_SIGNAL_FUNC(button_press_event), mdl_info); + + gtk_container_add(GTK_CONTAINER(mdl_info->glwindow), glarea); + gtk_widget_show(mdl_info->glwindow); + gtk_widget_show(glarea); + gtk_widget_realize(glarea); + + dialog->models_list=g_list_append(dialog->models_list,mdl_info); + + update_models_menu(mdl_info); +} + +void add_anim_button(GtkWidget *container,int num,char **pix) +{ + GtkStyle *style; + GdkBitmap *mask; + GdkPixmap *gdkpix; + GtkWidget *gtkpix,*button; + + button=gtk_button_new(); + gtk_container_add(GTK_CONTAINER(container),button); + gtk_widget_realize(button); + style = gtk_widget_get_style(button); + gdkpix = gdk_pixmap_create_from_xpm_d(button->window, + &mask, + &style->bg[GTK_STATE_NORMAL], + pix); + gtkpix = gtk_pixmap_new(gdkpix, mask); + gtk_widget_show(gtkpix); + gtk_container_add(GTK_CONTAINER(button),gtkpix); + gtk_signal_connect(GTK_OBJECT(button),"clicked", + GTK_SIGNAL_FUNC(on_anim_clicked),GINT_TO_POINTER(num)); + gtk_widget_show(button); +} + + +void display_model(ModelInfo *mdl,int mode) +{ + GLfloat m[4][4]; + int nextframe; + int frame; + float interp; + + DEBUG("%s",mdl->name); + + + if (!GTK_WIDGET_REALIZED(mdl->glarea)) return; + + if (mdl->model==NULL) return; + + begingl(mdl->glarea); + + if (!mdl->init) + { + initgl(mdl); + mdl->init = 1; + } + + if (mode==DRAW_NORMAL) + { + glClearColor(.3,.4,.6,0); + } + else + { + glClearColor(0,0,0,0); + } + + if (mode==DRAW_WHITE) glDisable(GL_TEXTURE_2D); + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + glTranslatef(mdl->obj_Xpos,mdl->obj_Ypos,mdl->obj_Zpos); + build_rotmatrix(m,mdl->curquat); + glMultMatrixf(&m[0][0]); + glRotatef(-90,1,0,0); + + if (mode==DRAW_COORD_S) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,mdl->texture_s); + } + else if (mode==DRAW_COORD_T) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,mdl->texture_t); + } + + + if (mdl->last>mdl->first) + { + frame=(int)mdl->frame; + nextframe=(int)mdl->frame+1; + if (nextframe>=mdl->model->numframes) nextframe=frame; + } + else + { + nextframe=(int)mdl->frame; + frame=(int)mdl->frame-1; + if (frame<0) frame=0; + } + + interp=mdl->frame-floor(mdl->frame); + + mdl->model->draw(mdl->model,frame,nextframe,interp); + + if (mode!=DRAW_NORMAL) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,mdl->texture); + } + + endgl(mdl->glarea); + gtk_gl_area_swapbuffers(GTK_GL_AREA(mdl->glarea)); +} + diff --git a/tools/texpaint/model.h b/tools/texpaint/model.h new file mode 100644 index 000000000..28506df6c --- /dev/null +++ b/tools/texpaint/model.h @@ -0,0 +1,81 @@ +/* Texture Paint - a GIMP plugin + * + * Copyright (C) 1998 Uwe Maurer + * + * Copyright (C) 1998 Lionel ULMER + * + * Based on code Copyright (C) 1997 Trey Harrison + * + * 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. + */ + +#ifndef __MODEL_H__ +#define __MODEL_H__ + +#include +#include +#include + +typedef struct +{ + gfloat x,y,z; +} vec3_t; + +typedef struct +{ + gint v[3]; + GLfloat tex[3][2]; +} triangle_t; + +typedef struct { + float x, y, z; + float nx, ny, xz; +} Vertex; + +typedef struct { + float s, t; +} TexInfo; + +typedef struct { + char name[16]; + + Vertex *vert_table; +} Frame; + +typedef struct _Model Model; + +struct _Model +{ + /* The number of Frames */ + long numframes; + Frame *frames; + + void (*draw)(Model *,int frame,int nextframe,float interpolation); + void (*destroy)(Model *); + + /* The GL commands */ + long *glcmds; + TexInfo *texinfo; + + int num_tris; + int num_verts; + triangle_t *tri; + vec3_t *vertex; +}; + +Model *Model1Load(char *name,FILE *f); /* mdl file*/ +Model *Model2Load(char *name,FILE *f); /* md2 file*/ + +#endif // __MODEL__H__ diff --git a/tools/texpaint/model1.c b/tools/texpaint/model1.c new file mode 100644 index 000000000..ae09a2178 --- /dev/null +++ b/tools/texpaint/model1.c @@ -0,0 +1,302 @@ +/* Texture Paint - a GIMP plugin + * + * Copyright (C) 1998 Uwe Maurer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "texturepaint.h" +#include "model.h" +#include "q1pal.h" + +#define MDL_VERSION 6 + +/* + MDL (Quake I) Model +*/ + +typedef struct +{ + gint32 ident; + gint32 version; + vec3_t scale; + vec3_t origin; + gfloat radius; + vec3_t offsets; + gint32 num_skins; + gint32 skin_width; + gint32 skin_height; + gint32 num_verts; + gint32 num_tris; + gint32 num_frames; + gint32 sync_type; + gint32 flags; + gfloat size; +} Model1Header; + +typedef struct +{ + gint32 onseam; + gint32 s; + gint32 t; +} stvert_t; + +typedef struct +{ + gint32 facesfront; + gint32 v[3]; +} mdl_triangle_t; + +typedef struct +{ + unsigned char p[3]; + unsigned char normal; +} vertex_t; + +typedef struct +{ + vertex_t min,max; + char name[16]; +} frame_t; + +static void destroy(Model *mdl) +{ + g_free(mdl->tri); + g_free(mdl->vertex); + g_free(mdl->frames); + g_free(mdl); +} + +static void draw(Model *mdl,int frame,int nextframe,float interp) +{ + int i,j,v; + vec3_t *vertex; + + gfloat x,y,z; + + + frame= (frame % mdl->numframes)*mdl->num_verts; + nextframe= (nextframe % mdl->numframes)*mdl->num_verts; + + vertex=mdl->vertex; + + + glBegin(GL_TRIANGLES); + + for (i=0;inum_tris;i++) + { + for (j=0;j<3;j++) + { + v=mdl->tri[i].v[j]; + + x= vertex[frame+v].x + + (vertex[nextframe+v].x-vertex[frame+v].x)*interp; + y= vertex[frame+v].y + + (vertex[nextframe+v].y-vertex[frame+v].y)*interp; + z= vertex[frame+v].z + + (vertex[nextframe+v].z-vertex[frame+v].z)*interp; + glTexCoord2fv(mdl->tri[i].tex[j]); + glVertex3f(x,y,z); + } + } + + glEnd(); +} + + +Model *Model1Load(char *name,FILE *fp) +{ + Model1Header header; + Model *mdl; + int i,k,f; + gint32 dummy; + guchar *texture; + gint size; + gint32 image_id,layer_id; + GimpPixelRgn rgn; + GimpDrawable *drawable; + gint w,h; + stvert_t *stvert; + mdl_triangle_t *triangle; + vertex_t *vertex; + frame_t frame; + gfloat x,y,z; + gint v; + gfloat xmin,xmax,ymax,ymin,zmax,zmin,scale; + char filename[300]; + + fread(&header,sizeof(header),1,fp); + if (strncmp((char *)&header.ident,"IDPO",4)!=0) return NULL; + if (header.version!=MDL_VERSION) return NULL; + mdl=g_malloc(sizeof(*mdl)); + memset(mdl,0,sizeof(*mdl)); + + mdl->num_tris=header.num_tris; + mdl->num_verts=header.num_verts; + + w=header.skin_width; + h=header.skin_height; + size=w*h; + texture=g_malloc(size); + + image_id=-1; + + for (i=0;itri=g_malloc(header.num_tris*sizeof(triangle_t)); + mdl->vertex=g_malloc(header.num_frames*header.num_verts*sizeof(mdl->vertex[0])); + + size=header.num_verts*sizeof(vertex_t); + vertex=g_malloc(size); + + mdl->frames=g_malloc(header.num_frames*sizeof(mdl->frames[0])); + mdl->numframes=header.num_frames; + + xmax=-G_MAXFLOAT; + ymax=-G_MAXFLOAT; + zmax=-G_MAXFLOAT; + xmin=+G_MAXFLOAT; + ymin=+G_MAXFLOAT; + zmin=+G_MAXFLOAT; + + for (f=k=0;fframes[f].name,frame.name,16); + + fread(vertex,size,1,fp); + + for (i=0;ivertex[k].x=x; + mdl->vertex[k].y=y; + mdl->vertex[k].z=z; + + if (x>xmax) xmax=x; + if (xymax) ymax=y; + if (yzmax) zmax=z; + if (zscale) scale=y; + if (z>scale) scale=z; + + if (scale) scale=1/scale; else scale=1; + + x=(xmax+xmin)/2; + y=(ymax+ymin)/2; + z=(zmax+zmin)/2; + + + + for (i=0;ivertex[i].x=(mdl->vertex[i].x-x)*scale; + mdl->vertex[i].y=(mdl->vertex[i].y-y)*scale; + mdl->vertex[i].z=(mdl->vertex[i].z-z)*scale; + } + + for (i=0;itri[i].v[k]=v; + mdl->tri[i].tex[k][0]=x; + mdl->tri[i].tex[k][1]=y; + } + } + + g_free(vertex); + g_free(stvert); + g_free(triangle); + + mdl->destroy=destroy; + mdl->draw=draw; + + return mdl; +} + + + + diff --git a/tools/texpaint/model2.c b/tools/texpaint/model2.c new file mode 100644 index 000000000..83e32a8c6 --- /dev/null +++ b/tools/texpaint/model2.c @@ -0,0 +1,357 @@ +/* Texture Paint - a GIMP plugin + * + * Copyright (C) 1998 Uwe Maurer + * + * Copyright (C) 1998 Lionel ULMER + * + * Based on code Copyright (C) 1997 Trey Harrison + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "model.h" +#include "texturepaint.h" + + +void FreeModel(Model *mdl); + +typedef struct { + float x, y, z; +} Vec3; + +/* + MD2 (Quake II) Model +*/ +typedef struct +{ + gint32 ident; + gint32 version; + gint32 skinwidth; + gint32 skinheight; + gint32 framesize; /* byte size of each frame*/ + gint32 num_skins; + gint32 num_xyz; + gint32 num_st; /* greater than num_xyz for seams*/ + gint32 num_tris; + gint32 num_glcmds; /* dwords in strip/fan command list*/ + gint32 num_frames; + gint32 ofs_skins; /* each skin is a MAX_SKINNAME string */ + gint32 ofs_st; /* byte offset from start for stverts */ + gint32 ofs_tris; /* offset for dtriangles */ + gint32 ofs_frames; /* offset for first frame */ + gint32 ofs_glcmds; + gint32 ofs_end; /* end of file */ +} Model2Header; + +typedef struct { + guchar x; + guchar y; /* X,Y,Z coordinate, packed on 0-255 */ + guchar z; + guchar lightnormalindex; /* index of the vertex normal */ +} Trivertex; + +typedef struct { + Vec3 scale; /* multiply byte verts by this */ + Vec3 origin; /* then add this */ + char name[16]; /* frame name from grabbing */ + Trivertex verts[1]; /* variable sized */ +} FrameInfo; + +typedef struct +{ + gint16 v[3]; + gint16 st[3]; +} d_triangle_t; + +typedef struct +{ + gint16 s,t; +} d_stvert_t; + +void DrawModel(Model *mdl, int frame, int nextframe, float ratio) { + int nb_vert; + long *command; + Frame *frame1, *frame2; + + /* Keeps the frame value valid */ + frame = frame % mdl->numframes; + nextframe = nextframe % mdl->numframes; + + /* Gets the frames information */ + frame1 = mdl->frames + frame; + frame2 = mdl->frames + nextframe; + + /* Do the gl commands */ + command = mdl->glcmds; + nb_vert = 0; + while (*command != 0) { + int num_verts, i; + + /* Determine the command to draw the triangles */ + if (*command > 0) { + /* Triangle strip */ + num_verts = *command; + glBegin(GL_TRIANGLE_STRIP); + } else { + /* Triangle fan */ + num_verts = -(*command); + glBegin(GL_TRIANGLE_FAN); + } + command++; + + for (i = 0; i < num_verts; i++) { + Vec3 p; /* Interpolated point */ + int vert_index; + + /* Grab the vertex index */ + vert_index = *command; command++; + + /* Interpolate */ + p.x = frame1->vert_table[vert_index].x + + (frame2->vert_table[vert_index].x - + frame1->vert_table[vert_index].x) * ratio; + p.y = frame1->vert_table[vert_index].y + + (frame2->vert_table[vert_index].y - + frame1->vert_table[vert_index].y) * ratio; + p.z = frame1->vert_table[vert_index].z + + (frame2->vert_table[vert_index].z - + frame1->vert_table[vert_index].z) * ratio; + + glTexCoord2f(mdl->texinfo[nb_vert].s, mdl->texinfo[nb_vert].t); + glVertex3f(p.x, p.y, p.z); + + nb_vert++; + } + + glEnd(); + } +} + +Model *Model2Load(char *name,FILE *f) { + int frame; + Model2Header mdl_header; + Model *mdl; + FrameInfo *frames; + long *glcmds; + long *command, *cmd_copy; + TexInfo *texinfo; + int i,k; + int num_vertices; + long offset; + d_triangle_t *d_tri; + d_stvert_t *d_stvert; + + gfloat x,y,z; + gfloat xmin,xmax; + gfloat ymin,ymax; + gfloat zmin,zmax,scale; + + /* Failsafe... */ + if (f == NULL) + return NULL; + + /* In case of a PAK loading */ + offset = ftell(f); + + /* Read the header*/ + fread(&mdl_header, sizeof(Model2Header), 1, f); + + /* Check if this is really a .MD2 file :-) */ + if (strncmp((char *) &(mdl_header.ident), "IDP2", 4)) + return NULL; + + /* Create the model */ + mdl = (Model *) malloc(sizeof(Model)); + memset(mdl, 0, sizeof(Model)); + + /* We do not need all the info from the header, just some of it*/ + mdl->numframes = mdl_header.num_frames; + + mdl->draw=DrawModel; + mdl->destroy=FreeModel; + + + /* Reads the GL commands */ + fseek(f, offset + mdl_header.ofs_glcmds, SEEK_SET); + glcmds = (long *) malloc(mdl_header.num_glcmds * sizeof(long)); + fread(glcmds, mdl_header.num_glcmds * sizeof(long), 1, f); + + /* We keep only the commands and the index in the glcommands. We + 'pre-parse' the texture coordinates */ + /* Do not ask me how I found this formula :-)) */ + num_vertices = ((mdl_header.num_tris + 2 * mdl_header.num_glcmds - 2) / 7); + + mdl->texinfo = (TexInfo *) malloc(sizeof(TexInfo) * num_vertices); + mdl->glcmds = (long *) + malloc(sizeof(long) * (mdl_header.num_glcmds - 2 * num_vertices)); + + /* Reads the frames */ + fseek(f, offset + mdl_header.ofs_frames, SEEK_SET); + frames = (FrameInfo *) malloc(mdl_header.framesize * mdl->numframes); + fread(frames, mdl_header.framesize * mdl->numframes, 1, f); + + /* Converts the FrameInfos to Frames */ + mdl->frames = (Frame *) malloc(sizeof(Frame) * mdl->numframes); + + xmax=-G_MAXFLOAT; + ymax=-G_MAXFLOAT; + zmax=-G_MAXFLOAT; + xmin=+G_MAXFLOAT; + ymin=+G_MAXFLOAT; + zmin=+G_MAXFLOAT; + + for (frame = 0; frame < mdl->numframes; frame++) + { + FrameInfo *frameinfo; + + /* Gets the frames information */ + frameinfo = (FrameInfo *) ((char *) frames + mdl_header.framesize * frame); + strcpy(mdl->frames[frame].name, frameinfo->name); + mdl->frames[frame].vert_table = (Vertex *) malloc(sizeof(Vertex) * + mdl_header.num_xyz); + + + /* Loads the vertices */ + for (i = 0; i < mdl_header.num_xyz; i++) + { + Vertex *p = (mdl->frames[frame].vert_table) + i; + + p->x = (float) frameinfo->verts[i].x * + frameinfo->scale.x + frameinfo->origin.x; + p->y = (float)frameinfo->verts[i].y * + frameinfo->scale.y + frameinfo->origin.y; + p->z = (float)frameinfo->verts[i].z * + frameinfo->scale.z + frameinfo->origin.z; + + if (p->xx; + if (p->x>xmax) xmax=p->x; + if (p->yy; + if (p->y>ymax) ymax=p->y; + if (p->zz; + if (p->z>zmax) zmax=p->z; + } + } + + x=(xmax-xmin)/2; + y=(ymax-ymin)/2; + z=(zmax-zmin)/2; + + scale=x; + if (y>scale) scale=y; + if (z>scale) scale=z; + + if (scale) scale=1/scale; else scale=1; + + x=(xmax+xmin)/2; + y=(ymax+ymin)/2; + z=(zmax+zmin)/2; + + for (frame = 0; frame < mdl->numframes; frame++) + { + for (i = 0; i < mdl_header.num_xyz; i++) + { + Vertex *p = (mdl->frames[frame].vert_table) + i; + + p->x=(p->x-x)*scale; + p->y=(p->y-y)*scale; + p->z=(p->z-z)*scale; + } + } + + /* Now transform the GL commands */ + command = glcmds; + cmd_copy = mdl->glcmds; + texinfo = mdl->texinfo; + while (*command != 0) { + int nb_verts, i; + + /* Determine the command to draw the triangles */ + if (*command > 0) + /* Triangle strip */ + nb_verts = *command; + else + /* Triangle fan */ + nb_verts = -(*command); + *(cmd_copy++) = *(command++); + + for (i = 0; i < nb_verts; i++) { + float s, t; + + /* Gets the texture information */ + s = *((float *) command); command++; + t = *((float *) command); command++; + texinfo->s = s; + texinfo->t = t; + texinfo++; + + /* We keep the vertex index */ + *(cmd_copy++) = *(command++); + } + } + /* Do not forget to copy the zero :-) */ + *(cmd_copy++) = *(command++); + + mdl->num_tris=mdl_header.num_tris; + mdl->tri = malloc(mdl->num_tris*sizeof(*mdl->tri)); + + fseek(f, offset + mdl_header.ofs_tris, SEEK_SET); + d_tri = malloc(mdl->num_tris*sizeof(*d_tri)); + fread(d_tri,mdl->num_tris*sizeof(*d_tri) , 1, f); + + fseek(f, offset + mdl_header.ofs_st, SEEK_SET); + d_stvert = malloc(mdl_header.num_st*sizeof(*d_stvert)); + fread(d_stvert,mdl_header.num_st*sizeof(*d_stvert) , 1, f); + + for (i=0;inum_tris;i++) + { + for (k=0;k<3;k++) + { + mdl->tri[i].v[k]=d_tri[i].v[k]; + mdl->tri[i].tex[k][0]=(float)d_stvert[d_tri[i].st[k]].s + /mdl_header.skinwidth; + mdl->tri[i].tex[k][1]=(float)d_stvert[d_tri[i].st[k]].t + /mdl_header.skinheight; + } + } + + g_free(d_tri); + g_free(d_stvert); + + /* Clean memory */ + free(frames); + free(glcmds); + + return mdl; +} + +/* Frees the memory used by a model */ +void FreeModel(Model *mdl) { + int frame; + + for (frame = 0; frame < mdl->numframes; frame++) + free(mdl->frames[frame].vert_table); + free(mdl->frames); + free(mdl->glcmds); + free(mdl->texinfo); + free(mdl); +} diff --git a/tools/texpaint/open.c b/tools/texpaint/open.c new file mode 100644 index 000000000..29eb1501d --- /dev/null +++ b/tools/texpaint/open.c @@ -0,0 +1,204 @@ +/* Texture Paint + * Plug-in for the GIMP + * + * Copyright (C) 1998 Uwe Maurer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include +#include +#include "texturepaint.h" +#include "model.h" +#include "pack.h" + +typedef struct +{ + GtkWidget *widget; + GtkWidget *tree; + FILE *fp; +} Data; + + +void model_new(char *,Model *mdl); +void update_images_menu(gint32 ); + +void on_pakdialog_destroy(GtkObject *obj,gpointer data) +{ + Data *d; + d=(Data *)data; + + fclose(d->fp); + g_free(d); +} + +void on_pak_close_clicked(GtkWidget *w,gpointer data) +{ + gtk_widget_destroy(GTK_WIDGET(data)); +} + + +void on_pak_open_clicked(GtkWidget *widget,gpointer data) +{ + GList *sel; + EntryInfo *entry; + Data *d; + Model *mdl; + FILE *tmp; + GtkWidget *item; + guchar *buf; + char name[256],*title; + gint32 image_id; + + GimpParam *return_vals; + gint nreturn_vals; + + d=(Data *)data; + + sel=GTK_TREE(d->tree)->selection; + + if (sel) + item=GTK_WIDGET(sel->data); + else + item=widget; + + + entry=GetInfo(item); + if (entry==NULL) return; + + fseek(d->fp,entry->offset,SEEK_SET); + + gtk_label_get(GTK_LABEL(GTK_BIN(item)->child),&title); + + mdl=model_load(title,d->fp); + + + if (mdl) + { + model_new(title,mdl); + } + else + { + tmp = tmpfile(); + if (tmp==NULL) return; + + fseek(d->fp,entry->offset,SEEK_SET); + + buf=g_malloc(entry->size); + fread(buf,1,entry->size,d->fp); + fwrite(buf,1,entry->size,tmp); + fclose(tmp); + g_free(buf); + + return_vals=gimp_run_procedure("gimp_file_load", + &nreturn_vals, + GIMP_PDB_INT32,GIMP_RUN_INTERACTIVE, + GIMP_PDB_STRING,name, + GIMP_PDB_STRING,name, GIMP_PDB_END); + + if (return_vals[0].data.d_status==GIMP_PDB_SUCCESS) + { + image_id=return_vals[1].data.d_image; + gimp_image_set_filename(image_id,title); + update_images_menu(image_id); + gimp_display_new(image_id); + gimp_displays_flush(); + } + + gimp_destroy_params(return_vals,nreturn_vals); + remove(name); + } +} + +void on_item_clicked(GtkWidget *widget,GdkEvent *ev,gpointer data) +{ + if (ev->type==GDK_2BUTTON_PRESS) + { + on_pak_open_clicked(widget,data); + } +} + +void open_pak_file(char *file) +{ + GtkWidget *dialog; + Data *data; + + dialog=create_pakdialog(); + + data=g_malloc(sizeof(data[0])); + data->widget=dialog; + + gtk_label_set(GTK_LABEL(get_widget(dialog,"filename")),file); + + + gtk_signal_connect(GTK_OBJECT(dialog),"destroy", + GTK_SIGNAL_FUNC(on_pakdialog_destroy),data); + + gtk_signal_connect(GTK_OBJECT(get_widget(dialog,"close")),"clicked", + GTK_SIGNAL_FUNC(on_pak_close_clicked),dialog); + + gtk_signal_connect(GTK_OBJECT(get_widget(dialog,"open")),"clicked", + GTK_SIGNAL_FUNC(on_pak_open_clicked),data); + + data->fp=fopen(file,"rb"); + if (data->fp==NULL) + { + gimp_message("Can't open PAK-file!"); + gtk_widget_destroy(dialog); + return; + } + + SetItemParams(GTK_SIGNAL_FUNC(on_item_clicked),data); + data->tree=OpenPAK(data->fp,"pakfile"); + + if (data->tree==NULL) + { + gimp_message("File is no PAK-file!"); + gtk_widget_destroy(dialog); + return; + } + + gtk_widget_show(data->tree); + gtk_container_add(GTK_CONTAINER(get_widget(dialog,"scrolledwindow")), + data->tree); + gtk_widget_show(dialog); +} + + + + + +Model * model_load(char *name,FILE *fp) +{ + int n; + + n=strlen(name); + + if (n<=4) return NULL; + + if (g_strcasecmp(&name[n-4],".md2")==0) + { + return Model2Load(name,fp); + } + else if (g_strcasecmp(&name[n-4],".mdl")==0) + { + return Model1Load(name,fp); + } + + return NULL; +} diff --git a/tools/texpaint/pack.c b/tools/texpaint/pack.c new file mode 100644 index 000000000..7499b7bc0 --- /dev/null +++ b/tools/texpaint/pack.c @@ -0,0 +1,278 @@ +/* GiMd2Viewer - Quake2 model viewer + * + * Copyright (C) 1998 Lionel ULMER + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include + +#include "pack.h" + +#define INFO_KEY "Entry Info" + +typedef struct { + unsigned char magic[4]; + long diroffset; + long dirsize; +} PakHeader; + +typedef struct { + char filename[0x38]; + long offset; + long size; +} PakEntry; + +typedef struct dir_entry { + char *name; + long offset; + long size; + + struct dir_entry *same_level; + struct dir_entry *sub_dir; +} DirEntry; + + +static GtkSignalFunc signal_func; +static gpointer signal_data; + +void SetItemParams(GtkSignalFunc f,gpointer data) +{ + signal_func=f; + signal_data=data; +} + +char *GetDir(char **file) { + char *tmp = *file; + int i; + + for (i = 0; (tmp[i] != '/') && (tmp[i] != '\0'); i++) ; + + if (tmp[i] == '\0') + return NULL; + + tmp[i] = '\0'; + *file = *file + i + 1; + + return tmp; +} + +static inline DirEntry *NewDirEntry(char *name, DirEntry *level, DirEntry *sub, + long offset, long size) { + DirEntry *ret = (DirEntry *) malloc(sizeof(DirEntry)); + + ret->name = name; + ret->same_level = level; + ret->sub_dir = sub; + + ret->offset = offset; + ret->size = size; + + return ret; +} + +static inline DirEntry *RecInsert(DirEntry *first, char *filename, + long offset, long size) { + char *dir, *subdir; + + subdir = filename; + dir = GetDir(&subdir); + + if (dir == NULL) { + /* This is a leaf (a file) */ + DirEntry *prec, *cur, *newentry; + + newentry = NewDirEntry(subdir, NULL, NULL, offset, size); + + prec = NULL; + cur = first; + + while (cur != NULL) { + if (strcmp(subdir, cur->name) <= 0) + break; + + prec = cur; + cur = cur->same_level; + } + + if (prec == NULL) { + newentry->same_level = first; + + return newentry; + } else { + prec->same_level = newentry; + newentry->same_level = cur; + + return first; + } + } else { + /* The file is in a directory */ + DirEntry *prec, *cur, *newentry; + + prec = NULL; + cur = first; + + while (cur != NULL) { + if (strcmp(dir, cur->name) <= 0) + break; + + prec = cur; + cur = cur->same_level; + } + + /* Already created subdirectory */ + if ((cur != NULL) && (strcmp(dir, cur->name) == 0)) { + cur->sub_dir = RecInsert(cur->sub_dir, subdir, offset, size); + + return first; + } + + /* Case of a new directory */ + newentry = NewDirEntry(dir, NULL, NULL, -1, -1); + newentry->sub_dir = RecInsert(NULL, subdir, offset, size); + + if (prec == NULL) { + newentry->same_level = first; + + return newentry; + } else { + prec->same_level = newentry; + newentry->same_level = cur; + + return first; + } + } +} + +static void item_destroyed(GtkWidget *widget, gpointer data) { + EntryInfo *info = (EntryInfo *) gtk_object_get_data(GTK_OBJECT(widget), + INFO_KEY); + + if (info == NULL) + return; + + free(info); + gtk_object_set_data(GTK_OBJECT(widget), + INFO_KEY, + NULL); +} + +static inline void BuildTree(GtkWidget *tree, DirEntry *de) { + while (de != NULL) { + GtkWidget *item; + + /* Creates a new tree item */ + item = gtk_tree_item_new_with_label(de->name); + gtk_tree_append(GTK_TREE(tree), item); + gtk_widget_show(item); + + if (de->sub_dir == NULL) { + /* This is a file !!!! */ + EntryInfo *info = (EntryInfo *) malloc(sizeof(EntryInfo)); + info->offset = de->offset; + info->size = de->size; + + gtk_object_set_data(GTK_OBJECT(item), + INFO_KEY, + (gpointer) info); + + if (signal_func) + { + gtk_widget_set_events(item, + GDK_BUTTON_PRESS_MASK|gtk_widget_get_events(item)); + + gtk_signal_connect(GTK_OBJECT(item),"button_press_event", + signal_func,signal_data); + } + + /* To free the memory */ + gtk_signal_connect(GTK_OBJECT(item), "destroy", + GTK_SIGNAL_FUNC(item_destroyed), NULL); + } else { + GtkWidget *stree; + + stree = gtk_tree_new(); + gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), stree); + gtk_tree_item_collapse(GTK_TREE_ITEM(item)); + BuildTree(stree, de->sub_dir); + } + + de = de->same_level; + } +} + +static inline void FreeMem(DirEntry *de) { + if (de == NULL) + return; + FreeMem(de->sub_dir); + FreeMem(de->same_level); + + /* No need to free the char *, it is freed with the PakEntries */ + free(de); +} + +EntryInfo *GetInfo(GtkWidget *item) { + return (EntryInfo *) gtk_object_get_data(GTK_OBJECT(item), + INFO_KEY); +} + +GtkWidget *OpenPAK(FILE *f, char *name) { + PakHeader header; + PakEntry *entries; + int num_entries; + int i; + DirEntry *first = NULL, *root; + GtkWidget *ret; + + /* Fail safe :-) */ + if (f == NULL) + return NULL; + + /* Loads the header */ + fread(&header, sizeof(PakHeader), 1, f); + + /* Check if this is really a PACK file */ + if (strncmp((char *) &(header.magic), "PACK", 4)) + return NULL; + + /* Goes to the start of the PAK directory */ + fseek(f, header.diroffset, SEEK_SET); + num_entries = header.dirsize / sizeof(PakEntry); + + /* Reads the PAK directory */ + entries = (PakEntry *) malloc(num_entries * sizeof(PakEntry)); + fread(entries, header.dirsize, 1, f); + + /* Builds the dir hierarchy */ + for (i = 0; i < num_entries; i++) { + first = RecInsert(first, entries[i].filename, + entries[i].offset, entries[i].size); + } + root = NewDirEntry(name, NULL, first, -1, -1); + + /* Builds the corresponding GtkTree */ + ret = gtk_tree_new(); + BuildTree(ret, root); + + /* Frees the memory */ + FreeMem(root); + free(entries); + + return ret; +} diff --git a/tools/texpaint/pack.h b/tools/texpaint/pack.h new file mode 100644 index 000000000..16a480c27 --- /dev/null +++ b/tools/texpaint/pack.h @@ -0,0 +1,32 @@ +/* GiMd2Viewer - Quake2 model viewer + * Copyright (C) 1998 Lionel ULMER + * + * 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. + */ + +#ifndef __PACK_H__ + +#include + +typedef struct entry_info { + long offset; + long size; +} EntryInfo; + +EntryInfo *GetInfo(GtkWidget *item) ; +GtkWidget *OpenPAK(FILE *f, char *name); +void SetItemParams(GtkSignalFunc func, gpointer data); + +#endif // __PACK_H__ diff --git a/tools/texpaint/q1pal.h b/tools/texpaint/q1pal.h new file mode 100644 index 000000000..a84a58e42 --- /dev/null +++ b/tools/texpaint/q1pal.h @@ -0,0 +1,258 @@ +static unsigned char q1pal[]={ +0x00, 0x00, 0x00, +0x0F, 0x0F, 0x0F, +0x1F, 0x1F, 0x1F, +0x2F, 0x2F, 0x2F, +0x3F, 0x3F, 0x3F, +0x4B, 0x4B, 0x4B, +0x5B, 0x5B, 0x5B, +0x6B, 0x6B, 0x6B, +0x7B, 0x7B, 0x7B, +0x8B, 0x8B, 0x8B, +0x9B, 0x9B, 0x9B, +0xAB, 0xAB, 0xAB, +0xBB, 0xBB, 0xBB, +0xCB, 0xCB, 0xCB, +0xDB, 0xDB, 0xDB, +0xEB, 0xEB, 0xEB, +0x0F, 0x0B, 0x07, +0x17, 0x0F, 0x0B, +0x1F, 0x17, 0x0B, +0x27, 0x1B, 0x0F, +0x2F, 0x23, 0x13, +0x37, 0x2B, 0x17, +0x3F, 0x2F, 0x17, +0x4B, 0x37, 0x1B, +0x53, 0x3B, 0x1B, +0x5B, 0x43, 0x1F, +0x63, 0x4B, 0x1F, +0x6B, 0x53, 0x1F, +0x73, 0x57, 0x1F, +0x7B, 0x5F, 0x23, +0x83, 0x67, 0x23, +0x8F, 0x6F, 0x23, +0x0B, 0x0B, 0x0F, +0x13, 0x13, 0x1B, +0x1B, 0x1B, 0x27, +0x27, 0x27, 0x33, +0x2F, 0x2F, 0x3F, +0x37, 0x37, 0x4B, +0x3F, 0x3F, 0x57, +0x47, 0x47, 0x67, +0x4F, 0x4F, 0x73, +0x5B, 0x5B, 0x7F, +0x63, 0x63, 0x8B, +0x6B, 0x6B, 0x97, +0x73, 0x73, 0xA3, +0x7B, 0x7B, 0xAF, +0x83, 0x83, 0xBB, +0x8B, 0x8B, 0xCB, +0x00, 0x00, 0x00, +0x07, 0x07, 0x00, +0x0B, 0x0B, 0x00, +0x13, 0x13, 0x00, +0x1B, 0x1B, 0x00, +0x23, 0x23, 0x00, +0x2B, 0x2B, 0x07, +0x2F, 0x2F, 0x07, +0x37, 0x37, 0x07, +0x3F, 0x3F, 0x07, +0x47, 0x47, 0x07, +0x4B, 0x4B, 0x0B, +0x53, 0x53, 0x0B, +0x5B, 0x5B, 0x0B, +0x63, 0x63, 0x0B, +0x6B, 0x6B, 0x0F, +0x07, 0x00, 0x00, +0x0F, 0x00, 0x00, +0x17, 0x00, 0x00, +0x1F, 0x00, 0x00, +0x27, 0x00, 0x00, +0x2F, 0x00, 0x00, +0x37, 0x00, 0x00, +0x3F, 0x00, 0x00, +0x47, 0x00, 0x00, +0x4F, 0x00, 0x00, +0x57, 0x00, 0x00, +0x5F, 0x00, 0x00, +0x67, 0x00, 0x00, +0x6F, 0x00, 0x00, +0x77, 0x00, 0x00, +0x7F, 0x00, 0x00, +0x13, 0x13, 0x00, +0x1B, 0x1B, 0x00, +0x23, 0x23, 0x00, +0x2F, 0x2B, 0x00, +0x37, 0x2F, 0x00, +0x43, 0x37, 0x00, +0x4B, 0x3B, 0x07, +0x57, 0x43, 0x07, +0x5F, 0x47, 0x07, +0x6B, 0x4B, 0x0B, +0x77, 0x53, 0x0F, +0x83, 0x57, 0x13, +0x8B, 0x5B, 0x13, +0x97, 0x5F, 0x1B, +0xA3, 0x63, 0x1F, +0xAF, 0x67, 0x23, +0x23, 0x13, 0x07, +0x2F, 0x17, 0x0B, +0x3B, 0x1F, 0x0F, +0x4B, 0x23, 0x13, +0x57, 0x2B, 0x17, +0x63, 0x2F, 0x1F, +0x73, 0x37, 0x23, +0x7F, 0x3B, 0x2B, +0x8F, 0x43, 0x33, +0x9F, 0x4F, 0x33, +0xAF, 0x63, 0x2F, +0xBF, 0x77, 0x2F, +0xCF, 0x8F, 0x2B, +0xDF, 0xAB, 0x27, +0xEF, 0xCB, 0x1F, +0xFF, 0xF3, 0x1B, +0x0B, 0x07, 0x00, +0x1B, 0x13, 0x00, +0x2B, 0x23, 0x0F, +0x37, 0x2B, 0x13, +0x47, 0x33, 0x1B, +0x53, 0x37, 0x23, +0x63, 0x3F, 0x2B, +0x6F, 0x47, 0x33, +0x7F, 0x53, 0x3F, +0x8B, 0x5F, 0x47, +0x9B, 0x6B, 0x53, +0xA7, 0x7B, 0x5F, +0xB7, 0x87, 0x6B, +0xC3, 0x93, 0x7B, +0xD3, 0xA3, 0x8B, +0xE3, 0xB3, 0x97, +0xAB, 0x8B, 0xA3, +0x9F, 0x7F, 0x97, +0x93, 0x73, 0x87, +0x8B, 0x67, 0x7B, +0x7F, 0x5B, 0x6F, +0x77, 0x53, 0x63, +0x6B, 0x4B, 0x57, +0x5F, 0x3F, 0x4B, +0x57, 0x37, 0x43, +0x4B, 0x2F, 0x37, +0x43, 0x27, 0x2F, +0x37, 0x1F, 0x23, +0x2B, 0x17, 0x1B, +0x23, 0x13, 0x13, +0x17, 0x0B, 0x0B, +0x0F, 0x07, 0x07, +0xBB, 0x73, 0x9F, +0xAF, 0x6B, 0x8F, +0xA3, 0x5F, 0x83, +0x97, 0x57, 0x77, +0x8B, 0x4F, 0x6B, +0x7F, 0x4B, 0x5F, +0x73, 0x43, 0x53, +0x6B, 0x3B, 0x4B, +0x5F, 0x33, 0x3F, +0x53, 0x2B, 0x37, +0x47, 0x23, 0x2B, +0x3B, 0x1F, 0x23, +0x2F, 0x17, 0x1B, +0x23, 0x13, 0x13, +0x17, 0x0B, 0x0B, +0x0F, 0x07, 0x07, +0xDB, 0xC3, 0xBB, +0xCB, 0xB3, 0xA7, +0xBF, 0xA3, 0x9B, +0xAF, 0x97, 0x8B, +0xA3, 0x87, 0x7B, +0x97, 0x7B, 0x6F, +0x87, 0x6F, 0x5F, +0x7B, 0x63, 0x53, +0x6B, 0x57, 0x47, +0x5F, 0x4B, 0x3B, +0x53, 0x3F, 0x33, +0x43, 0x33, 0x27, +0x37, 0x2B, 0x1F, +0x27, 0x1F, 0x17, +0x1B, 0x13, 0x0F, +0x0F, 0x0B, 0x07, +0x6F, 0x83, 0x7B, +0x67, 0x7B, 0x6F, +0x5F, 0x73, 0x67, +0x57, 0x6B, 0x5F, +0x4F, 0x63, 0x57, +0x47, 0x5B, 0x4F, +0x3F, 0x53, 0x47, +0x37, 0x4B, 0x3F, +0x2F, 0x43, 0x37, +0x2B, 0x3B, 0x2F, +0x23, 0x33, 0x27, +0x1F, 0x2B, 0x1F, +0x17, 0x23, 0x17, +0x0F, 0x1B, 0x13, +0x0B, 0x13, 0x0B, +0x07, 0x0B, 0x07, +0xFF, 0xF3, 0x1B, +0xEF, 0xDF, 0x17, +0xDB, 0xCB, 0x13, +0xCB, 0xB7, 0x0F, +0xBB, 0xA7, 0x0F, +0xAB, 0x97, 0x0B, +0x9B, 0x83, 0x07, +0x8B, 0x73, 0x07, +0x7B, 0x63, 0x07, +0x6B, 0x53, 0x00, +0x5B, 0x47, 0x00, +0x4B, 0x37, 0x00, +0x3B, 0x2B, 0x00, +0x2B, 0x1F, 0x00, +0x1B, 0x0F, 0x00, +0x0B, 0x07, 0x00, +0x00, 0x00, 0xFF, +0x0B, 0x0B, 0xEF, +0x13, 0x13, 0xDF, +0x1B, 0x1B, 0xCF, +0x23, 0x23, 0xBF, +0x2B, 0x2B, 0xAF, +0x2F, 0x2F, 0x9F, +0x2F, 0x2F, 0x8F, +0x2F, 0x2F, 0x7F, +0x2F, 0x2F, 0x6F, +0x2F, 0x2F, 0x5F, +0x2B, 0x2B, 0x4F, +0x23, 0x23, 0x3F, +0x1B, 0x1B, 0x2F, +0x13, 0x13, 0x1F, +0x0B, 0x0B, 0x0F, +0x2B, 0x00, 0x00, +0x3B, 0x00, 0x00, +0x4B, 0x07, 0x00, +0x5F, 0x07, 0x00, +0x6F, 0x0F, 0x00, +0x7F, 0x17, 0x07, +0x93, 0x1F, 0x07, +0xA3, 0x27, 0x0B, +0xB7, 0x33, 0x0F, +0xC3, 0x4B, 0x1B, +0xCF, 0x63, 0x2B, +0xDB, 0x7F, 0x3B, +0xE3, 0x97, 0x4F, +0xE7, 0xAB, 0x5F, +0xEF, 0xBF, 0x77, +0xF7, 0xD3, 0x8B, +0xA7, 0x7B, 0x3B, +0xB7, 0x9B, 0x37, +0xC7, 0xC3, 0x37, +0xE7, 0xE3, 0x57, +0x7F, 0xBF, 0xFF, +0xAB, 0xE7, 0xFF, +0xD7, 0xFF, 0xFF, +0x67, 0x00, 0x00, +0x8B, 0x00, 0x00, +0xB3, 0x00, 0x00, +0xD7, 0x00, 0x00, +0xFF, 0x00, 0x00, +0xFF, 0xF3, 0x93, +0xFF, 0xF7, 0xC7, +0xFF, 0xFF, 0xFF, +0x9F, 0x5B, 0x53 +}; diff --git a/tools/texpaint/texturepaint.c b/tools/texpaint/texturepaint.c new file mode 100644 index 000000000..c27508d46 --- /dev/null +++ b/tools/texpaint/texturepaint.c @@ -0,0 +1,1540 @@ +/* Texture Paint + * Plug-in for the GIMP + * + * Copyright (C) 1998 Uwe Maurer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "texturepaint.h" +#include "config.h" + +#include "Pixmaps/begin.xpm" +#include "Pixmaps/end.xpm" +#include "Pixmaps/stop.xpm" +#include "Pixmaps/play.xpm" + +Dialog *dialog; + + +int max_tex_size=64; +int red_bits,green_bits,blue_bits; +int red_shift,green_shift,blue_shift; // 8-red_bits + +/* GIMP PLUGIN*/ +/*******************************************************************************/ + +MAIN () + +static void query(void); +static void run(gchar *name, + gint nparams, + GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); + +GimpPlugInInfo PLUG_IN_INFO= +{ + NULL, + NULL, + query, + run +}; + +/*******************************************************************************/ + +static int round_size(int size,gboolean floor) +{ + static int s[]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192}; + int i; + + if (size>=max_tex_size) return max_tex_size; + + if (floor) + { + for (i=0;i<=12;i++) + { + if (s[i]==size) return size; + if (s[i]update_texture || mdl->playing) + { + if (mdl->idle<0) + mdl->idle=gtk_idle_add_priority(10,(GtkFunction)model_draw,mdl); + } + else + { + if (mdl->idle>=0) + { + gtk_idle_remove(mdl->idle); + mdl->idle=-1; + } + } +} + + +void set_parameter(ModelInfo *mdl) +{ + GLint v; + + v=(GTK_TOGGLE_BUTTON(dialog->linear)->active) ? GL_LINEAR : GL_NEAREST; + + glBindTexture(GL_TEXTURE_2D, mdl->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, v); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, v); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + v=(GTK_TOGGLE_BUTTON(dialog->fastest)->active) ? GL_FASTEST : GL_NICEST; + + glHint(GL_PERSPECTIVE_CORRECTION_HINT,v); +} + + +/* radiobuttons */ + +void on_button_toggled(GtkToggleButton *button,gpointer data) +{ + if (dialog->mdl==NULL) return; + + begingl(dialog->mdl->glarea); + set_parameter(dialog->mdl); + + dialog->mdl->update_texture=GTK_TOGGLE_BUTTON(dialog->update)->active; + set_idle(dialog->mdl); + + model_draw(dialog->mdl); + endgl(dialog->mdl->glarea); +} + +void on_update_clicked(GtkButton *button,gpointer data) +{ + ModelInfo *mdl; + + if (data) mdl=(ModelInfo *)data; + else if (dialog->mdl) mdl=dialog->mdl; + else return; + + if (get_texture(mdl)<0) + { + gimp_message("Select a correct texture first."); + } + + model_draw(mdl); +} + + +static void init_special_texture(ModelInfo *mdl,int w,int h) +{ + guchar *image; + int x,pos; + int red_mask,green_mask,blue_mask; + + begingl(mdl->glarea); + + red_mask= (1<>red_bits) & green_mask)<>(red_bits+green_bits)) & blue_mask)<texture_s); + glBindTexture(GL_TEXTURE_2D,mdl->texture_s); + glTexImage2D(GL_TEXTURE_2D,0,3,w,1,0, + GL_RGB,GL_UNSIGNED_BYTE,image); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + + glGenTextures(1,&mdl->texture_t); + glBindTexture(GL_TEXTURE_2D,mdl->texture_t); + glTexImage2D(GL_TEXTURE_2D,0,3,1,h,0, + GL_RGB,GL_UNSIGNED_BYTE,image); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + + g_free(image); + endgl(mdl->glarea); +} + + +gint model_draw(ModelInfo *mdl) +{ + gdouble frametime; + + DEBUG("%s",mdl->name); + + if (mdl->drawing) + { + return TRUE; + } + + mdl->drawing=TRUE; + + if (mdl->update_texture) + { + if (get_texture(mdl)<0) + { + mdl->update_texture=FALSE; + set_idle(mdl); + if (dialog->mdl==mdl) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(dialog->update),0); + } + } + + if (mdl->playing) + { + frametime=g_timer_elapsed(mdl->timer,NULL); + + g_timer_start(mdl->timer); + + if (mdl->last > mdl->first) + { + mdl->frame+=mdl->fps*frametime; + if (mdl->frame>(gdouble)mdl->last) mdl->frame=mdl->first; + if (mdl->frame<(gdouble)mdl->first) mdl->frame=mdl->first; + } + else if (mdl->lastfirst) + { + mdl->frame-=mdl->fps*frametime; + if (mdl->frame<(gdouble)mdl->last) mdl->frame=mdl->first; + if (mdl->frame>(gdouble)mdl->first) mdl->frame=mdl->first; + } + else + { + mdl->frame=mdl->first; + } + + if (mdl==dialog->mdl) + { + gtk_adjustment_set_value(GTK_ADJUSTMENT(gtk_range_get_adjustment(GTK_RANGE(dialog->cur_frame))),mdl->frame); + + } + } + + display_model(mdl,DRAW_NORMAL); + mdl->drawing=FALSE; + return TRUE; +} + + + +static void query(void) +{ + static GimpParamDef args[]= + { + {GIMP_PDB_INT32,"run_mode","Interactive, non-interactive"}, + }; + gint nargs = sizeof(args) / sizeof(args[0]); + + gimp_install_procedure("plug_in_texture_paint", + "Paint on a Quake 1/2 Model", + "", + "Uwe Maurer ", + "Uwe Maurer, Lionel Ulmer, Janne Löf, Trey Harrison", + "1998", + "/Xtns/Texture Paint", + "", + GIMP_EXTENSION, + nargs,0, + args,NULL); +} + +int get_texture(ModelInfo *mdl) +{ + guchar *tex; + gint w,h; + GimpPixelRgn rgn; + GimpDrawable *drawable; + gint32 drawable_id; + + DEBUG("%s",mdl->name); + + if (!check_texture(mdl->tex_image)) + { + glDisable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + return -1; + } + + drawable_id=gimp_image_get_active_layer(mdl->tex_image); + drawable=gimp_drawable_get(drawable_id); + + w=gimp_drawable_width(drawable->id); + h=gimp_drawable_height(drawable->id); + + tex=g_malloc(3*w*h); + gimp_pixel_rgn_init(&rgn,drawable,0,0,w,h,FALSE,FALSE); + + gimp_pixel_rgn_get_rect(&rgn,tex,0,0,w,h); + BindTexture(mdl,tex,w,h); + g_free(tex); + gimp_drawable_detach(drawable); + + glEnable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + + + return 0; +} + + +void on_load_clicked(GtkButton *button,gpointer data) +{ + + gtk_widget_show(dialog->fileselection); +} + +void on_cancel_clicked(GtkButton *button,gpointer data) +{ + gtk_widget_hide(dialog->fileselection); +} + +void on_ok_clicked(GtkButton *button,gpointer data) +{ + char *filename; + Model *mdl; + FILE *fp; + int len; + + gtk_widget_hide(dialog->fileselection); + + filename=gtk_file_selection_get_filename( + GTK_FILE_SELECTION(dialog->fileselection)); + + + if (!filename || (len=strlen(filename))<=4) + { + gimp_message("Can't open Model!"); + return; + } + + if (g_strcasecmp(&filename[len-4],".pak")==0) + { + open_pak_file(filename); + } + else if ((g_strcasecmp(&filename[len-4],".md2") == 0) || (g_strcasecmp(&filename[len-4],".mdl") == 0)) + { + fp=fopen(filename,"rb"); + if (fp==NULL || (mdl=model_load(filename,fp))==NULL) + { + gimp_message("Can't open file!"); + fclose(fp); + return; + } + fclose(fp); + model_new(filename,mdl); + } + else + { + gimp_message("Unknown file!"); + } +} + +gboolean on_fileselection_delete(GtkWidget *w,GdkEvent *ev,gpointer data) +{ + gtk_widget_hide(dialog->fileselection); + return TRUE; +} + +void set_image_item(gint32 image_id) +{ + GtkWidget *menu,*item; + GList *list; + gint pos,i; + gint32 image; + gint32 drawable; + char str[100]; + int w,h,bpp; + + DEBUG("%i",image_id); + + gtk_widget_set_sensitive(dialog->scale,(image_id>=0)); + + str[0]='\0'; + + if (image_id>=0) + { + drawable=gimp_image_get_active_layer(image_id); + if (drawable>=0) + { + w=gimp_drawable_width(drawable); + h=gimp_drawable_height(drawable); + bpp=gimp_drawable_bpp(drawable); + + sprintf(str,"%ix%i, %i bpp",w,h,bpp); + + if (!check_texture(image_id)) + { + strcat(str,": no texture"); + } + else + { + strcat(str,": texture ok"); + } + dialog->oldwidth=round_size(w,FALSE); + dialog->oldheight=round_size(h,FALSE); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->width),dialog->oldwidth); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->height),dialog->oldheight); + } + else strcpy(str,"no active layer"); + } + + if (dialog->mdl) + DEBUG("%s %i",dialog->mdl->name,dialog->mdl->tex_image); + + if (dialog->mdl && dialog->mdl->tex_image!=image_id) + { + dialog->mdl->tex_image=image_id; + get_texture(dialog->mdl); + model_draw(dialog->mdl); + } + + gtk_label_set(GTK_LABEL(dialog->info),str); + + menu=gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->images_menu)); + + list=gtk_container_children(GTK_CONTAINER(menu)); + + pos=0; + + for (i=0;list;list=list->next,i++) + { + item=GTK_WIDGET(list->data); + image=GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),IMAGE_KEY)); + if (image==image_id) pos=i; + } + + gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->images_menu),pos); +} + +static void update_value(GtkAdjustment *a,gpointer data) +{ + int n; + ModelInfo *mdl; + char *name; + + + n=GPOINTER_TO_INT(data); + mdl=dialog->mdl; + if (!mdl) return; + + switch(n) + { + case 1: + mdl->frame=a->value; + model_draw(mdl); + name=mdl->model->frames[(int)mdl->frame].name; + gtk_label_set(GTK_LABEL(dialog->frame_info2),name); + break; + case 2: mdl->first=(int)a->value; break; + case 3: mdl->last=(int)a->value; break; + case 4: mdl->fps=a->value; break; + + } + +} + +void on_anim_clicked(GtkButton *button,gpointer data) +{ + int n; + ModelInfo *mdl; + + n=GPOINTER_TO_INT(data); + mdl=dialog->mdl; + if (!mdl) return; + + switch(n) + { + case 1: + mdl->playing=TRUE; + set_idle(mdl); + gtk_widget_set_sensitive(dialog->cur_frame,FALSE); + g_timer_start(mdl->timer); + break; + case 2: + mdl->playing=FALSE; + gtk_widget_set_sensitive(dialog->cur_frame,TRUE); + set_idle(mdl); + break; + case 3: + mdl->frame=mdl->first; + gtk_adjustment_set_value(GTK_ADJUSTMENT + (gtk_range_get_adjustment(GTK_RANGE(dialog->cur_frame))),mdl->frame); + break; + case 4: + mdl->frame=mdl->last; + gtk_adjustment_set_value(GTK_ADJUSTMENT + (gtk_range_get_adjustment(GTK_RANGE(dialog->cur_frame))),mdl->frame); + break; + } +} + + +void set_model_item(ModelInfo *model) +{ + ModelInfo *mdl,*m; + int i,pos; + GtkWidget *menu,*item; + GList *list; + char str[256]; + GtkObject *adjustment; + + if (model) DEBUG("%s",model->name); + + menu=gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->models_menu)); + + list=gtk_container_children(GTK_CONTAINER(menu)); + + pos=-1; + mdl=NULL; + + for (i=0;list;list=list->next,i++) + { + item=GTK_WIDGET(list->data); + m=gtk_object_get_data(GTK_OBJECT(item),MODEL_KEY); + if (m==model) + { + pos=i; + mdl=m; + } + } + DEBUG("%i",pos); + dialog->mdl=mdl; + + if (mdl) + { + gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->models_menu),pos); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(dialog->update), + dialog->mdl->update_texture); + + update_images_menu(dialog->mdl->tex_image); + + + gtk_widget_set_sensitive(dialog->frame_info,TRUE); + gtk_widget_set_sensitive(dialog->frame_info2,TRUE); + gtk_widget_set_sensitive(dialog->cur_frame,TRUE); + gtk_widget_set_sensitive(dialog->start_frame,TRUE); + gtk_widget_set_sensitive(dialog->end_frame,TRUE); + gtk_widget_set_sensitive(dialog->fps,TRUE); + + sprintf(str,"%i frames",(int)mdl->model->numframes); + gtk_label_set(GTK_LABEL(dialog->frame_info),str); + + adjustment=gtk_adjustment_new(mdl->frame,0,mdl->model->numframes-1,1,1,0); + gtk_range_set_adjustment(GTK_RANGE(dialog->cur_frame),GTK_ADJUSTMENT(adjustment)); + gtk_signal_connect(GTK_OBJECT(adjustment),"value_changed", + GTK_SIGNAL_FUNC(update_value),GINT_TO_POINTER(1)); + update_value(GTK_ADJUSTMENT(adjustment),GINT_TO_POINTER(1)); + + adjustment=gtk_adjustment_new(mdl->first,0,mdl->model->numframes-1,1,1,0); + gtk_range_set_adjustment(GTK_RANGE(dialog->start_frame),GTK_ADJUSTMENT(adjustment)); + gtk_signal_connect(GTK_OBJECT(adjustment),"value_changed", + GTK_SIGNAL_FUNC(update_value),GINT_TO_POINTER(2)); + update_value(GTK_ADJUSTMENT(adjustment),GINT_TO_POINTER(2)); + + adjustment=gtk_adjustment_new(mdl->last,0,mdl->model->numframes-1,1,1,0); + gtk_range_set_adjustment(GTK_RANGE(dialog->end_frame),GTK_ADJUSTMENT(adjustment)); + gtk_signal_connect(GTK_OBJECT(adjustment),"value_changed", + GTK_SIGNAL_FUNC(update_value),GINT_TO_POINTER(3)); + update_value(GTK_ADJUSTMENT(adjustment),GINT_TO_POINTER(3)); + + adjustment=gtk_adjustment_new(15,.1,30,1,1,0); + gtk_range_set_adjustment(GTK_RANGE(dialog->fps),GTK_ADJUSTMENT(adjustment)); + gtk_signal_connect(GTK_OBJECT(adjustment),"value_changed", + GTK_SIGNAL_FUNC(update_value),GINT_TO_POINTER(4)); + update_value(GTK_ADJUSTMENT(adjustment),GINT_TO_POINTER(4)); + } + else + { + gtk_widget_set_sensitive(dialog->frame_info,FALSE); + gtk_widget_set_sensitive(dialog->frame_info2,FALSE); + gtk_widget_set_sensitive(dialog->cur_frame,FALSE); + gtk_widget_set_sensitive(dialog->start_frame,FALSE); + gtk_widget_set_sensitive(dialog->end_frame,FALSE); + gtk_widget_set_sensitive(dialog->fps,FALSE); + + update_images_menu(-1); + } +} + +static void model_activate(GtkWidget *widget) +{ + ModelInfo *mdl; + + mdl=gtk_object_get_data(GTK_OBJECT(widget),MODEL_KEY); + + set_model_item(mdl); + +} + +void update_models_menu(ModelInfo *mdl) +{ + GtkWidget *menu,*item; + GList *list; + GtkWidget *option_menu; + char *name; + + if (mdl) DEBUG("%s",mdl->name); + + menu=gtk_menu_new(); + + list=dialog->models_list; + option_menu=dialog->models_menu; + + if (g_list_length(list)==0) + { + item=gtk_menu_item_new_with_label("none"); + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu),item); + gtk_widget_set_sensitive(option_menu,FALSE); + } + else + { + gtk_widget_set_sensitive(option_menu,TRUE); + for (;list;list=list->next) + { + name=((ModelInfo*)list->data)->name; + + item=gtk_menu_item_new_with_label(name); + gtk_object_set_data(GTK_OBJECT(item),MODEL_KEY,list->data); + gtk_signal_connect(GTK_OBJECT(item),"activate",GTK_SIGNAL_FUNC(model_activate),NULL); + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu),item); + } + } + + gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu),menu); + set_model_item(mdl); +} + +static gboolean check_size(int w,int h) +{ + int i; + + for (i=1;i<=max_tex_size;i*=2) + { + if (i==w) break; + } + + if (i>max_tex_size) return FALSE; + + for (i=1;i<=max_tex_size;i*=2) + { + if (i==h) break; + } + + if (i>max_tex_size) return FALSE; + return TRUE; +} + +gboolean check_texture(gint32 image) +{ + gint32 drawable_id; + gint bpp,w,h; + + if (image<0) return FALSE; + + drawable_id=gimp_image_get_active_layer(image); + + if (drawable_id<0) return FALSE; + + bpp=gimp_drawable_bpp(drawable_id); + + if (bpp!=3) return FALSE; + + w=gimp_drawable_width(drawable_id); + h=gimp_drawable_height(drawable_id); + + return check_size(w,h); +} + +static void image_activate(GtkWidget *item) +{ + gint32 image; + + image=GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),IMAGE_KEY)); + set_image_item(image); +} + +void update_images_menu(gint32 image_id) +{ + gint32 *images; + gint nimages,i,pos; + GtkWidget *item; + GtkWidget *menu; + gchar *name; + gint32 old_image; + + + DEBUG("%i",image_id); + + menu=gtk_menu_new(); + + images=gimp_image_list(&nimages); + + item=gtk_menu_item_new_with_label("none"); + gtk_object_set_data(GTK_OBJECT(item),IMAGE_KEY,GINT_TO_POINTER(-1)); + gtk_signal_connect(GTK_OBJECT(item),"activate",GTK_SIGNAL_FUNC(image_activate),NULL); + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu),item); + + pos=0; + + item=GTK_OPTION_MENU(dialog->images_menu)->menu_item; + if (item) old_image=GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),IMAGE_KEY)); + else old_image=-1; + + for (i=0;iimages_menu),menu); + gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->images_menu),pos); + + set_image_item(image_id); +} + +void on_images_menu_enter(GtkButton *widget,gpointer data) +{ + if (dialog->mdl) + update_images_menu(dialog->mdl->tex_image); + else + update_images_menu(-1); +} + +void on_scale_clicked(GtkButton *b,gpointer data) +{ + gint w,h; + GtkWidget *item; + gint32 image_id; + GimpParam *return_val; + gint nreturn_val; + gboolean new_display; + + + w=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->width)); + h=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->height)); + + item=GTK_OPTION_MENU(dialog->images_menu)->menu_item; + image_id=GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item),IMAGE_KEY)); + + new_display=FALSE; + + if (GTK_TOGGLE_BUTTON(dialog->new_image)->active) + { + return_val=gimp_run_procedure("gimp_channel_ops_duplicate", + &nreturn_val,GIMP_PDB_IMAGE,image_id,GIMP_PDB_END); + if (return_val[0].data.d_status!=GIMP_PDB_SUCCESS) + { + gimp_destroy_params(return_val,nreturn_val); + gimp_message("gimp_channel_ops_duplicate failed!"); + return; + } + gimp_destroy_params(return_val,nreturn_val); + image_id=return_val[1].data.d_image; + new_display=TRUE; + } + + if (image_id<0) + { + gimp_message("Select an image first."); + return; + } + + return_val=gimp_run_procedure("gimp_image_scale", + &nreturn_val, + GIMP_PDB_IMAGE,image_id, + GIMP_PDB_INT32,w, + GIMP_PDB_INT32,h, + GIMP_PDB_END); + + if (return_val[0].data.d_status!=GIMP_PDB_SUCCESS) + { + gimp_destroy_params(return_val,nreturn_val); + gimp_message("gimp_image_scale failed!"); + return; + } + gimp_destroy_params(return_val,nreturn_val); + + if (gimp_image_base_type(image_id)!=GIMP_RGB) + { + return_val=gimp_run_procedure("gimp_convert_rgb", + &nreturn_val, + GIMP_PDB_IMAGE,image_id, + GIMP_PDB_END); + if (return_val[0].data.d_status!=GIMP_PDB_SUCCESS) + { + gimp_destroy_params(return_val,nreturn_val); + gimp_message("gimp_convert_rgb failed!"); + return; + } + gimp_destroy_params(return_val,nreturn_val); + } + + update_images_menu(image_id); + + if (dialog->mdl) + { + get_texture(dialog->mdl); + model_draw(dialog->mdl); + } + + if (new_display) + { + gimp_display_new(image_id); + gimp_displays_flush(); + } +} + +void on_base_texture_clicked(GtkButton *b,gpointer data) +{ + gint w,h; + gint32 image_id; + gint32 layer_id; + GimpDrawable *drawable; + guchar backgr[3],foregr[3]; + GimpParam *return_val; + gint nreturn_val; + gdouble points[4]; + int j,i,k; + Model *mdl; + + gchar brush[1024]; + gdouble opacity; + gint32 mode; + + + + + if (dialog->mdl==NULL) return; + mdl=dialog->mdl->model; + + gimp_palette_get_background(&backgr[0],&backgr[1],&backgr[2]); + gimp_palette_get_foreground(&foregr[0],&foregr[1],&foregr[2]); + + return_val=gimp_run_procedure("gimp_brushes_get_brush", + &nreturn_val,GIMP_PDB_END); + + if (return_val[0].data.d_status == GIMP_PDB_SUCCESS) + { + strncpy(brush,return_val[1].data.d_string,sizeof(brush)); + } + else + { + brush[0]='\0'; + } + gimp_destroy_params(return_val,nreturn_val); + + + return_val=gimp_run_procedure("gimp_brushes_get_opacity", + &nreturn_val,GIMP_PDB_END); + + if (return_val[0].data.d_status==GIMP_PDB_SUCCESS) + { + opacity=return_val[1].data.d_float; + } + else + { + opacity=100; + } + gimp_destroy_params(return_val,nreturn_val); + + + return_val=gimp_run_procedure("gimp_brushes_get_paint_mode", + &nreturn_val,GIMP_PDB_END); + + if (return_val[0].data.d_status==GIMP_PDB_SUCCESS) + { + mode=return_val[1].data.d_int32; + } + else + { + mode=GIMP_NORMAL_MODE; + } + gimp_destroy_params(return_val,nreturn_val); + + + gimp_palette_set_foreground(255,255,255); + gimp_palette_set_background(0,0,0); + + w=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->width)); + h=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->height)); + + image_id=gimp_image_new(w,h,GIMP_RGB); + gimp_image_set_filename(image_id,"Base Texture"); + layer_id=gimp_layer_new(image_id,"Base Texture",w,h,GIMP_RGB_IMAGE,100,GIMP_NORMAL_MODE); + gimp_image_add_layer(image_id,layer_id,0); + + drawable=gimp_drawable_get(layer_id); + gimp_drawable_fill(layer_id,0); + + return_val=gimp_run_procedure("gimp_brushes_set_brush",&nreturn_val, + GIMP_PDB_STRING,"Circle (01)",GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); + + return_val=gimp_run_procedure("gimp_brushes_set_paint_mode",&nreturn_val, + GIMP_PDB_INT32,GIMP_NORMAL_MODE,GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); + + return_val=gimp_run_procedure("gimp_brushes_set_opacity",&nreturn_val, + GIMP_PDB_FLOAT,(gdouble)100.0,GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); + + for (k=0;knum_tris;k++) + { + j=2; + for (i=0;i<3;j=i++) + { + points[0]=(double)mdl->tri[k].tex[j][0]*w; + points[1]=(double)mdl->tri[k].tex[j][1]*h; + points[2]=(double)mdl->tri[k].tex[i][0]*w; + points[3]=(double)mdl->tri[k].tex[i][1]*h; + + return_val=gimp_run_procedure("gimp_paintbrush", + &nreturn_val, + GIMP_PDB_IMAGE,image_id, + GIMP_PDB_DRAWABLE,layer_id, + GIMP_PDB_FLOAT,(gdouble)0.0, + GIMP_PDB_INT32,4, + GIMP_PDB_FLOATARRAY,&points[0],GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); + } + } + gimp_drawable_detach(drawable); + + gimp_display_new(image_id); + gimp_image_clean_all(image_id); + gimp_displays_flush(); + + gimp_palette_set_background(backgr[0],backgr[1],backgr[2]); + gimp_palette_set_foreground(foregr[0],foregr[1],foregr[2]); + + return_val=gimp_run_procedure("gimp_brushes_set_brush",&nreturn_val, + GIMP_PDB_STRING,brush,GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); + + return_val=gimp_run_procedure("gimp_brushes_set_paint_mode",&nreturn_val, + GIMP_PDB_INT32,mode,GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); + + return_val=gimp_run_procedure("gimp_brushes_set_opacity",&nreturn_val, + GIMP_PDB_FLOAT,opacity,GIMP_PDB_END); + gimp_destroy_params(return_val,nreturn_val); +} + + + +static void on_spin_button_changed(GtkSpinButton *button,gpointer data) +{ + int val,oldval; + + oldval=val=gtk_spin_button_get_value_as_int(button); + + switch(GPOINTER_TO_INT(data)) + { + case 1: + if (valoldwidth) + val=round_size(val,TRUE); + else + val=round_size(val,FALSE); + + dialog->oldwidth=val; + break; + case 2: + if (valoldheight) + val=round_size(val,TRUE); + else + val=round_size(val,FALSE); + + dialog->oldheight=val; + break; + + } + + if (val!=oldval) gtk_spin_button_set_value(button,val); +} + +void init_dialog(void) +{ + GtkWidget *w; + gchar version[256]; + + if (dialog) g_free(dialog); + + dialog=g_malloc(sizeof(dialog[0])); + memset(dialog,0,sizeof(dialog[0])); + + dialog->widget=create_dialog(); + dialog->fileselection=create_fileselection(); + dialog->info=get_widget(dialog->widget,"info"); + dialog->nearest=get_widget(dialog->widget,"nearest"); + dialog->linear=get_widget(dialog->widget,"linear"); + dialog->fastest=get_widget(dialog->widget,"fastest"); + dialog->nicest=get_widget(dialog->widget,"nicest"); + dialog->update=get_widget(dialog->widget,"update"); + dialog->images_menu=get_widget(dialog->widget,"images_menu"); + dialog->models_menu=get_widget(dialog->widget,"models_menu"); + dialog->scale=get_widget(dialog->widget,"scale"); + dialog->new_image=get_widget(dialog->widget,"new_image"); + + dialog->frame_info=get_widget(dialog->widget,"frame_info"); + dialog->frame_info2=get_widget(dialog->widget,"frame_info2"); + dialog->cur_frame=get_widget(dialog->widget,"cur_frame"); + dialog->start_frame=get_widget(dialog->widget,"start_frame"); + dialog->end_frame=get_widget(dialog->widget,"end_frame"); + dialog->fps=get_widget(dialog->widget,"fps"); + + dialog->update_time=get_widget(dialog->widget,"update_time"); + + dialog->width=get_widget(dialog->widget,"width"); + dialog->height=get_widget(dialog->widget,"height"); + gtk_signal_connect(GTK_OBJECT(dialog->width),"changed", + GTK_SIGNAL_FUNC(on_spin_button_changed),GINT_TO_POINTER(1)); + gtk_signal_connect(GTK_OBJECT(dialog->height),"changed", + GTK_SIGNAL_FUNC(on_spin_button_changed),GINT_TO_POINTER(2)); + + w=get_widget(dialog->widget,"anim_hbox"); + add_anim_button(w,1,play_xpm); + add_anim_button(w,2,stop_xpm); + add_anim_button(w,3,begin_xpm); + add_anim_button(w,4,end_xpm); + + sprintf(version,"Texture Paint %s",VERSION); + gtk_label_set(GTK_LABEL(get_widget(dialog->widget,"version")),version); + dialog->paint_image=-1; + dialog->texture_drawable=-1; + + + + gtk_widget_show(dialog->widget); + + update_models_menu(NULL); +} + + +void on_dialog_destroy(GtkObject *obj,gpointer data) +{ + + gtk_main_quit(); +} + +void on_glwindow_destroy(GtkObject *obj,gpointer data) +{ + ModelInfo *mdl; + + mdl=gtk_object_get_data(obj,MODEL_KEY); + if (mdl==NULL) return; /* should never happen*/ + + if (mdl->idle>=0) gtk_idle_remove(mdl->idle); + + mdl->model->destroy(mdl->model); + + g_free(mdl->name); + + if (mdl->tex_s) g_free(mdl->tex_s); + if (mdl->tex_t) g_free(mdl->tex_t); + + g_timer_destroy(mdl->timer); + + g_free(mdl); + + dialog->models_list=g_list_remove(dialog->models_list,mdl); + + if (dialog->models_list) + update_models_menu((ModelInfo *)dialog->models_list->data); + else + update_models_menu(NULL); + +} + +void on_close_clicked(GtkButton *button,gpointer data) +{ + gtk_main_quit(); +} + +static void run(gchar *name, + gint nparams, + GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam val[1]; + + gint argc; + gchar **argv; + + argc=1; + argv=g_new(gchar *,1); + argv[0]=g_strdup("Texture Paint"); + + gtk_init(&argc, &argv); + gtk_rc_parse(gimp_gtkrc()); + gdk_set_use_xshm(gimp_use_xshm()); + + val[0].type=GIMP_PDB_STATUS; + val[0].data.d_status=GIMP_PDB_SUCCESS; + + *nreturn_vals=1; + *return_vals=val; + + init_dialog(); + +#if 0 +{ + FILE *f; + Model *mdl; + + f=fopen("/home/bob/coding/qview/data/players/male/tris.md2","rb"); + mdl = ModelLoad(f); + fclose(f); + + model_new("test1",mdl); + + f=fopen("/home/bob/coding/qview/data/players/male/tris.md2","rb"); + mdl = ModelLoad(f); + fclose(f); + + model_new("test2",mdl); +} +#endif + + gtk_main(); +} + + + + +static void get_size(ModelInfo *mdl,int *w,int *h) +{ + GLint data[4]; + + begingl(mdl->glarea); + glGetIntegerv(GL_VIEWPORT,data); + *w=data[2]; + *h=data[3]; + endgl(mdl->glarea); +} + +static void get_image(ModelInfo *mdl,guchar **image,int w,int h,int bpp) +{ + guchar *buf,*tmp; + int y; + int stride; + + begingl(mdl->glarea); + + buf=g_malloc(w*h*bpp); + tmp=g_malloc(w*h*3); + + glPixelStorei(GL_PACK_ALIGNMENT,1); + glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,tmp); + + endgl(mdl->glarea); + + + if (bpp==3) + { + stride=w*3; + + for (y=0;y>red_shift; + val+=((guint)buf[pos+1]>>green_shift)<>blue_shift)<<(red_bits+green_bits); + dest[x+y*w]=val; + pos+=3; + } + } + *data=dest; +} + +static void save_st(ModelInfo *mdl,int w,int h) +{ + guchar *buffer; + + + mdl->oldw=w; + mdl->oldh=h; + + + if (mdl->tex_s) g_free(mdl->tex_s); + display_model(mdl,DRAW_COORD_S); + get_image(mdl,&buffer,w,h,3); + decode(&mdl->tex_s,buffer,w,h); + g_free(buffer); + + if (mdl->tex_t) g_free(mdl->tex_t); + display_model(mdl,DRAW_COORD_T); + get_image(mdl,&buffer,w,h,3); + decode(&mdl->tex_t,buffer,w,h); + g_free(buffer); +} + +void on_paint_clicked(GtkButton *button,gpointer data) +{ + gint w,h; + gint32 image_id; + gint32 display_id; + gint32 layer_id,mask_id; + gint32 bglayer_id; + guchar r,g,b; + + gint32 *images; + gint nimages; + gint32 *layers; + gint nlayers; + gint i; + gboolean new_image; + ModelInfo *mdl; + + + + if (data) mdl=(ModelInfo *)data; + else if (dialog->mdl) mdl=dialog->mdl; + else return; + + DEBUG("%s",mdl->name); + + if (get_texture(mdl)<0) + { + gimp_message("Select a texture image first."); + return; + } + layer_id=gimp_image_get_active_layer(mdl->tex_image); + w=gimp_drawable_width(layer_id); + h=gimp_drawable_height(layer_id); + + init_special_texture(mdl,w,h); // FIXME oldw==w + + get_size(mdl,&w,&h); + + save_st(mdl,w,h); + + new_image=TRUE; + + if (mdl->paint_image>=0) + { + images=gimp_image_list(&nimages); + + for (i=0;ipaint_image==images[i]) + { + new_image=FALSE; + break; + } + } + g_free(images); + } + + + if (new_image) + { + image_id=gimp_image_new(w,h,GIMP_RGB); + mdl->paint_image=image_id; + + gimp_image_set_filename(image_id,"3D Paint"); + } + else + { + image_id=mdl->paint_image; + layers=gimp_image_get_layers(image_id,&nlayers); + + for (i=0;imdl) mdl=dialog->mdl; + else return; + + if (mdl->paint_image<0) + { + gimp_message("Click on the \"3D Paint\" button first."); + return; + } + + image_id=mdl->paint_image; + + drawable_id=gimp_image_get_active_layer(image_id); + + if (drawable_id<0) + { + gimp_message("Can't get active layer!"); + return; + } + + src_w=gimp_drawable_width(drawable_id); + src_h=gimp_drawable_height(drawable_id); + bpp=gimp_drawable_bpp(drawable_id); + + if (src_w!=mdl->oldw || src_h!=mdl->oldh || bpp!=4) + { + sprintf(str,"The image must be %ix%i (4 bpp)!",mdl->oldw,mdl->oldh); + gimp_message(str); + return; + } + if (!check_texture(mdl->tex_image)) + { + gimp_message("check_texture() failed!"); + return; + } + + drawable=gimp_drawable_get(drawable_id); + + src=g_malloc(4*src_w*src_h); + + gimp_pixel_rgn_init(&pr,drawable,0,0,src_w,src_h,FALSE,FALSE); + gimp_pixel_rgn_get_rect(&pr,src,0,0,src_w,src_h); + + gimp_drawable_flush(drawable); + gimp_drawable_detach(drawable); + + drawable_id=gimp_image_get_active_layer(mdl->tex_image); + + drawable=gimp_drawable_get(drawable_id); + + w=gimp_drawable_width(drawable->id); + h=gimp_drawable_height(drawable->id); + + dest=g_malloc(3*w*h); + + buffer=g_malloc(w*h*sizeof(gint32[4])); + + memset(buffer,0,w*h*sizeof(gint32[4])); + + gimp_pixel_rgn_init(&pr,drawable,0,0,w,h,TRUE,FALSE); + gimp_pixel_rgn_get_rect(&pr,dest,0,0,w,h); + + + for (y=0;ytex_s[x+y*src_w]-1; + t=mdl->tex_t[x+y*src_w]-1; + + if (s>0 && t>0) + { + pos1=(s+t*w)*4; + pos2=(x+y*src_w)*4; + + buffer[pos1]+=src[pos2]; + buffer[pos1+1]+=src[pos2+1]; + buffer[pos1+2]+=src[pos2+2]; + buffer[pos1+3]++; + } + } + } + + for (pos1=pos2=y=0;yglarea); + BindTexture(mdl,dest,w,h); + endgl(mdl->glarea); + + display_model(mdl,DRAW_NORMAL); + + g_free(src); + g_free(dest); + g_free(buffer); + + gimp_drawable_update(drawable_id,0,0,w,h); + gimp_displays_flush(); +} diff --git a/tools/texpaint/texturepaint.h b/tools/texpaint/texturepaint.h new file mode 100644 index 000000000..db80e4ce9 --- /dev/null +++ b/tools/texpaint/texturepaint.h @@ -0,0 +1,181 @@ +/* Texture Paint + * Plug-in for the GIMP + * + * Copyright (C) 1998 Uwe Maurer + * + * Based on GiMd2Viewer-0.1 (Quake2 model viewer) by + * Copyright (C) 1998 Lionel ULMER + * Copyright (C) 1997-1998 Janne Löf + * + * 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. + */ +#ifndef __TEXTUREPAINT_H_ +#define __TEXTUREPAINT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "trackball.h" +#include "model.h" +#include "gladesig.h" +#include "gladesrc.h" + +#define DRAW_NORMAL 0 +#define DRAW_WHITE 1 +#define DRAW_COORD_S 2 +#define DRAW_COORD_T 3 + + +#define IMAGE_KEY "image_id" /* for gtk_object_set_data */ +#define MODEL_KEY "model" + +#if 0 + +#define DEBUG(fmt,x...) printf(__FUNCTION__ " %i : " fmt "\n" , __LINE__ , ##x); + + +#else + +#define DEBUG(fmt,x...) ; + +#endif + + +typedef struct +{ + char *name; + + GtkWidget *glwindow; + GtkWidget *glarea; + + Model *model; + + int init; + + gint32 tex_image; + gint32 paint_image; + + GLint texture; + GLint texture_s; + GLint texture_t; + + gint16 *tex_s; + gint16 *tex_t; + + int oldw,oldh; + + gint idle; + + gint x1,x2,y1,y2; /* texture drawable*/ + gint w,h; /* x2-x1+1, y2-y1+1 */ + + gboolean update_texture; + + gboolean drawing; + + /*Animation*/ + GTimer *timer; + gboolean playing; + gdouble fps; + gdouble frame; + int first; + int last; + + + /* Trackball */ + float M1_beginx, M1_beginy; /* Last recorded mouse position */ + float curquat[4]; /* Current quaternion */ + float lastquat[4]; /* Last quaternion */ + + /* Object movement */ + float obj_Xpos; + float obj_Ypos; + float obj_Zpos; + int M2_beginx, M2_beginy, M3_beginy; +} ModelInfo; + +typedef struct +{ + GtkWidget *widget; + GtkWidget *info; + GtkWidget *nearest; + GtkWidget *linear; + GtkWidget *fastest; + GtkWidget *nicest; + GtkWidget *update; + GtkWidget *update_time; + GtkWidget *fileselection; + GtkWidget *images_menu; + GtkWidget *models_menu; + GtkWidget *scale; + GtkWidget *new_image; + + GtkWidget *frame_info; + GtkWidget *frame_info2; + GtkWidget *cur_frame; + GtkWidget *start_frame; + GtkWidget *end_frame; + GtkWidget *fps; + + GtkWidget *width,*height; + int oldwidth,oldheight; + + gint32 texture_drawable; + gint32 paint_image; + + GList *models_list; + + ModelInfo *mdl; + +} Dialog; + +extern Dialog *dialog; + +/* open.c */ +void open_pak_file(char *file); + +extern int max_tex_size; +extern int red_bits,green_bits,blue_bits; +extern int red_shift,green_shift,blue_shift; // 8-red_bits + + +gint model_draw(ModelInfo *); +Model *model_load(char *name,FILE *fp); + +void begingl(GtkWidget *); +void endgl(GtkWidget *); +void set_parameter(ModelInfo *mdl); +void BindTexture(ModelInfo *mdl,char *texdata,int w,int h); +void add_anim_button(GtkWidget *container,int num,char **pix); +int get_texture(ModelInfo *mdl); +void model_new(char *name,Model *mdl); +void on_anim_clicked(GtkButton *,gpointer); +void update_models_menu(ModelInfo *mdl); +void display_model(ModelInfo *,int mode); +gboolean check_texture(gint32 image); +void update_images_menu(gint32 image_id); +void on_paint_clicked(GtkButton *button,gpointer data); + + +#endif diff --git a/tools/texpaint/trackball.c b/tools/texpaint/trackball.c new file mode 100644 index 000000000..f23d3db30 --- /dev/null +++ b/tools/texpaint/trackball.c @@ -0,0 +1,324 @@ +/* + * (c) Copyright 1993, 1994, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* + * Trackball code: + * + * Implementation of a virtual trackball. + * Implemented by Gavin Bell, lots of ideas from Thant Tessman and + * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129. + * + * Vector manip code: + * + * Original code from: + * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli + * + * Much mucking with by: + * Gavin Bell + */ +#include +#include "trackball.h" + +/* + * This size should really be based on the distance from the center of + * rotation to the point on the object underneath the mouse. That + * point would then track the mouse as closely as possible. This is a + * simple example, though, so that is left as an Exercise for the + * Programmer. + */ +#define TRACKBALLSIZE (0.8) + +/* + * Local function prototypes (not defined in trackball.h) + */ +static float tb_project_to_sphere(float, float, float); +static void normalize_quat(float [4]); + +void +vzero(float *v) +{ + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; +} + +void +vset(float *v, float x, float y, float z) +{ + v[0] = x; + v[1] = y; + v[2] = z; +} + +void +vsub(const float *src1, const float *src2, float *dst) +{ + dst[0] = src1[0] - src2[0]; + dst[1] = src1[1] - src2[1]; + dst[2] = src1[2] - src2[2]; +} + +void +vcopy(const float *v1, float *v2) +{ + register int i; + for (i = 0 ; i < 3 ; i++) + v2[i] = v1[i]; +} + +void +vcross(const float *v1, const float *v2, float *cross) +{ + float temp[3]; + + temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); + vcopy(temp, cross); +} + +float +vlength(const float *v) +{ + return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +void +vscale(float *v, float div) +{ + v[0] *= div; + v[1] *= div; + v[2] *= div; +} + +void +vnormal(float *v) +{ + vscale(v,1.0/vlength(v)); +} + +float +vdot(const float *v1, const float *v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void +vadd(const float *src1, const float *src2, float *dst) +{ + dst[0] = src1[0] + src2[0]; + dst[1] = src1[1] + src2[1]; + dst[2] = src1[2] + src2[2]; +} + +/* + * Ok, simulate a track-ball. Project the points onto the virtual + * trackball, then figure out the axis of rotation, which is the cross + * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) + * Note: This is a deformed trackball-- is a trackball in the center, + * but is deformed into a hyperbolic sheet of rotation away from the + * center. This particular function was chosen after trying out + * several variations. + * + * It is assumed that the arguments to this routine are in the range + * (-1.0 ... 1.0) + */ +void +trackball(float q[4], float p1x, float p1y, float p2x, float p2y) +{ + float a[3]; /* Axis of rotation */ + float phi; /* how much to rotate about axis */ + float p1[3], p2[3], d[3]; + float t; + + if (p1x == p2x && p1y == p2y) { + /* Zero rotation */ + vzero(q); + q[3] = 1.0; + return; + } + + /* + * First, figure out z-coordinates for projection of P1 and P2 to + * deformed sphere + */ + vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y)); + vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y)); + + /* + * Now, we want the cross product of P1 and P2 + */ + vcross(p2,p1,a); + + /* + * Figure out how much to rotate around that axis. + */ + vsub(p1,p2,d); + t = vlength(d) / (2.0*TRACKBALLSIZE); + + /* + * Avoid problems with out-of-control values... + */ + if (t > 1.0) t = 1.0; + if (t < -1.0) t = -1.0; + phi = 2.0 * asin(t); + + axis_to_quat(a,phi,q); +} + +/* + * Given an axis and angle, compute quaternion. + */ +void +axis_to_quat(float a[3], float phi, float q[4]) +{ + vnormal(a); + vcopy(a,q); + vscale(q,sin(phi/2.0)); + q[3] = cos(phi/2.0); +} + +/* + * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet + * if we are away from the center of the sphere. + */ +static float +tb_project_to_sphere(float r, float x, float y) +{ + float d, t, z; + + d = sqrt(x*x + y*y); + if (d < r * 0.70710678118654752440) { /* Inside sphere */ + z = sqrt(r*r - d*d); + } else { /* On hyperbola */ + t = r / 1.41421356237309504880; + z = t*t / d; + } + return z; +} + +/* + * Given two rotations, e1 and e2, expressed as quaternion rotations, + * figure out the equivalent single rotation and stuff it into dest. + * + * This routine also normalizes the result every RENORMCOUNT times it is + * called, to keep error from creeping in. + * + * NOTE: This routine is written so that q1 or q2 may be the same + * as dest (or each other). + */ + +#define RENORMCOUNT 97 + +void +add_quats(float q1[4], float q2[4], float dest[4]) +{ + static int count=0; + float t1[4], t2[4], t3[4]; + float tf[4]; + + vcopy(q1,t1); + vscale(t1,q2[3]); + + vcopy(q2,t2); + vscale(t2,q1[3]); + + vcross(q2,q1,t3); + vadd(t1,t2,tf); + vadd(t3,tf,tf); + tf[3] = q1[3] * q2[3] - vdot(q1,q2); + + dest[0] = tf[0]; + dest[1] = tf[1]; + dest[2] = tf[2]; + dest[3] = tf[3]; + + if (++count > RENORMCOUNT) { + count = 0; + normalize_quat(dest); + } +} + +/* + * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0 + * If they don't add up to 1.0, dividing by their magnitued will + * renormalize them. + * + * Note: See the following for more information on quaternions: + * + * - Shoemake, K., Animating rotation with quaternion curves, Computer + * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985. + * - Pletinckx, D., Quaternion calculus as a basic tool in computer + * graphics, The Visual Computer 5, 2-13, 1989. + */ +static void +normalize_quat(float q[4]) +{ + int i; + float mag; + + mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); + for (i = 0; i < 4; i++) q[i] /= mag; +} + +/* + * Build a rotation matrix, given a quaternion rotation. + * + */ +void +build_rotmatrix(float m[4][4], float q[4]) +{ + m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]); + m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]); + m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]); + m[0][3] = 0.0; + + m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]); + m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]); + m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]); + m[1][3] = 0.0; + + m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]); + m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]); + m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]); + m[2][3] = 0.0; + + m[3][0] = 0.0; + m[3][1] = 0.0; + m[3][2] = 0.0; + m[3][3] = 1.0; +} + diff --git a/tools/texpaint/trackball.h b/tools/texpaint/trackball.h new file mode 100644 index 000000000..b676fb4e5 --- /dev/null +++ b/tools/texpaint/trackball.h @@ -0,0 +1,78 @@ +/* + * (c) Copyright 1993, 1994, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* + * trackball.h + * A virtual trackball implementation + * Written by Gavin Bell for Silicon Graphics, November 1988. + */ + +/* + * Pass the x and y coordinates of the last and current positions of + * the mouse, scaled so they are from (-1.0 ... 1.0). + * + * The resulting rotation is returned as a quaternion rotation in the + * first paramater. + */ +void +trackball(float q[4], float p1x, float p1y, float p2x, float p2y); + +/* + * Given two quaternions, add them together to get a third quaternion. + * Adding quaternions to get a compound rotation is analagous to adding + * translations to get a compound translation. When incrementally + * adding rotations, the first argument here should be the new + * rotation, the second and third the total rotation (which will be + * over-written with the resulting new total rotation). + */ +void +add_quats(float *q1, float *q2, float *dest); + +/* + * A useful function, builds a rotation matrix in Matrix based on + * given quaternion. + */ +void +build_rotmatrix(float m[4][4], float q[4]); + +/* + * This function computes a quaternion based on an axis (defined by + * the given vector) and an angle about which to rotate. The angle is + * expressed in radians. The result is put into the third argument. + */ +void +axis_to_quat(float a[3], float phi, float q[4]); +