From c64cd0cd05ef3d237097ff38d1da727a88bb7c7c Mon Sep 17 00:00:00 2001 From: Timothee TTimo Besset Date: Sat, 7 Apr 2012 18:53:01 -0500 Subject: [PATCH 01/16] Q2Tools source - didn't import this in initially --- tools/quake2/extra/COPYING.txt | 281 ++ tools/quake2/extra/Unpack/Unpack.dsp | 72 + tools/quake2/extra/Unpack/Unpack.dsw | 29 + tools/quake2/extra/Unpack/Unpack.java | 198 ++ tools/quake2/extra/bsp/bsp.mak | 1776 ++++++++++ tools/quake2/extra/bsp/bspinfo3/bspinfo3.c | 56 + tools/quake2/extra/bsp/bspinfo3/makefile | 53 + tools/quake2/extra/bsp/qbsp3/brushbsp.c | 1330 +++++++ tools/quake2/extra/bsp/qbsp3/csg.c | 635 ++++ tools/quake2/extra/bsp/qbsp3/faces.c | 1076 ++++++ tools/quake2/extra/bsp/qbsp3/gldraw.c | 232 ++ tools/quake2/extra/bsp/qbsp3/glfile.c | 149 + tools/quake2/extra/bsp/qbsp3/leakfile.c | 100 + tools/quake2/extra/bsp/qbsp3/makefile | 98 + tools/quake2/extra/bsp/qbsp3/map.c | 1017 ++++++ tools/quake2/extra/bsp/qbsp3/nodraw.c | 47 + tools/quake2/extra/bsp/qbsp3/portals.c | 1111 ++++++ tools/quake2/extra/bsp/qbsp3/prtfile.c | 287 ++ tools/quake2/extra/bsp/qbsp3/qbsp.h | 355 ++ tools/quake2/extra/bsp/qbsp3/qbsp3.c | 537 +++ tools/quake2/extra/bsp/qbsp3/textures.c | 221 ++ tools/quake2/extra/bsp/qbsp3/tree.c | 219 ++ tools/quake2/extra/bsp/qbsp3/writebsp.c | 590 ++++ tools/quake2/extra/bsp/qrad3/lightmap.c | 1316 +++++++ tools/quake2/extra/bsp/qrad3/makefile | 77 + tools/quake2/extra/bsp/qrad3/patches.c | 515 +++ tools/quake2/extra/bsp/qrad3/qrad.h | 158 + tools/quake2/extra/bsp/qrad3/qrad3.c | 717 ++++ tools/quake2/extra/bsp/qrad3/trace.c | 295 ++ tools/quake2/extra/bsp/qvis3/flow.c | 788 +++++ tools/quake2/extra/bsp/qvis3/makefile | 62 + tools/quake2/extra/bsp/qvis3/qvis3.c | 615 ++++ tools/quake2/extra/bsp/qvis3/vis.h | 149 + tools/quake2/extra/common/bspfile.c | 789 +++++ tools/quake2/extra/common/bspfile.h | 129 + tools/quake2/extra/common/cmdlib.c | 1055 ++++++ tools/quake2/extra/common/cmdlib.h | 145 + tools/quake2/extra/common/l3dslib.c | 301 ++ tools/quake2/extra/common/l3dslib.h | 27 + tools/quake2/extra/common/lbmlib.c | 824 +++++ tools/quake2/extra/common/lbmlib.h | 40 + tools/quake2/extra/common/mathlib.c | 174 + tools/quake2/extra/common/mathlib.h | 77 + tools/quake2/extra/common/mdfour.c | 224 ++ tools/quake2/extra/common/mdfour.h | 54 + tools/quake2/extra/common/polylib.c | 642 ++++ tools/quake2/extra/common/polylib.h | 55 + tools/quake2/extra/common/qfiles.h | 486 +++ tools/quake2/extra/common/scriplib.c | 297 ++ tools/quake2/extra/common/scriplib.h | 45 + tools/quake2/extra/common/threads.c | 448 +++ tools/quake2/extra/common/threads.h | 31 + tools/quake2/extra/common/trilib.c | 187 + tools/quake2/extra/common/trilib.h | 33 + tools/quake2/extra/qdata/anorms.h | 184 + tools/quake2/extra/qdata/images.c | 763 ++++ tools/quake2/extra/qdata/makefile | 81 + tools/quake2/extra/qdata/models.c | 1152 ++++++ tools/quake2/extra/qdata/qdata.c | 551 +++ tools/quake2/extra/qdata/qdata.dsp | 204 ++ tools/quake2/extra/qdata/qdata.dsw | 29 + tools/quake2/extra/qdata/qdata.h | 89 + tools/quake2/extra/qdata/qdata.mak | 549 +++ tools/quake2/extra/qdata/sprites.c | 228 ++ tools/quake2/extra/qdata/tables.c | 172 + tools/quake2/extra/qdata/video.c | 1259 +++++++ tools/quake2/extra/qe4/brush.c | 1568 +++++++++ tools/quake2/extra/qe4/brush.h | 87 + tools/quake2/extra/qe4/bspfile.h | 378 ++ tools/quake2/extra/qe4/camera.c | 594 ++++ tools/quake2/extra/qe4/camera.h | 63 + tools/quake2/extra/qe4/cmdlib.c | 686 ++++ tools/quake2/extra/qe4/cmdlib.h | 99 + tools/quake2/extra/qe4/csg.c | 168 + tools/quake2/extra/qe4/drag.c | 457 +++ tools/quake2/extra/qe4/eclass.c | 281 ++ tools/quake2/extra/qe4/entity.c | 538 +++ tools/quake2/extra/qe4/entity.h | 84 + tools/quake2/extra/qe4/entityw.h | 66 + tools/quake2/extra/qe4/glingr.h | 98 + tools/quake2/extra/qe4/icon1.ico | Bin 0 -> 766 bytes tools/quake2/extra/qe4/lbmlib.c | 835 +++++ tools/quake2/extra/qe4/lbmlib.h | 40 + tools/quake2/extra/qe4/makefile | 23 + tools/quake2/extra/qe4/map.c | 661 ++++ tools/quake2/extra/qe4/map.h | 53 + tools/quake2/extra/qe4/mathlib.c | 131 + tools/quake2/extra/qe4/mathlib.h | 66 + tools/quake2/extra/qe4/mru.c | 671 ++++ tools/quake2/extra/qe4/mru.h | 101 + tools/quake2/extra/qe4/parse.c | 141 + tools/quake2/extra/qe4/parse.h | 34 + tools/quake2/extra/qe4/points.c | 155 + tools/quake2/extra/qe4/q.bmp | Bin 0 -> 13878 bytes tools/quake2/extra/qe4/qe3.c | 451 +++ tools/quake2/extra/qe4/qe3.h | 306 ++ tools/quake2/extra/qe4/qe4.mak | 3716 ++++++++++++++++++++ tools/quake2/extra/qe4/qedefs.h | 117 + tools/quake2/extra/qe4/qfiles.h | 389 ++ tools/quake2/extra/qe4/resource.h | 308 ++ tools/quake2/extra/qe4/select.c | 706 ++++ tools/quake2/extra/qe4/select.h | 62 + tools/quake2/extra/qe4/textures.c | 1147 ++++++ tools/quake2/extra/qe4/textures.h | 70 + tools/quake2/extra/qe4/toolbar1.bmp | Bin 0 -> 1918 bytes tools/quake2/extra/qe4/vertsel.c | 245 ++ tools/quake2/extra/qe4/view.h | 52 + tools/quake2/extra/qe4/win_cam.c | 273 ++ tools/quake2/extra/qe4/win_dlg.c | 653 ++++ tools/quake2/extra/qe4/win_ent.c | 1137 ++++++ tools/quake2/extra/qe4/win_main.c | 1327 +++++++ tools/quake2/extra/qe4/win_qe3.aps | Bin 0 -> 78688 bytes tools/quake2/extra/qe4/win_qe3.c | 605 ++++ tools/quake2/extra/qe4/win_qe3.rc | 693 ++++ tools/quake2/extra/qe4/win_xy.c | 306 ++ tools/quake2/extra/qe4/win_z.c | 195 + tools/quake2/extra/qe4/xy.c | 973 +++++ tools/quake2/extra/qe4/xy.h | 48 + tools/quake2/extra/qe4/z.c | 426 +++ tools/quake2/extra/qe4/z.h | 42 + tools/quake2/extra/texpaint/docs.txt | 38 + tools/quake2/extra/texpaint/resource.h | 58 + tools/quake2/extra/texpaint/texmake.aps | Bin 0 -> 33472 bytes tools/quake2/extra/texpaint/texmake.rc | 156 + tools/quake2/extra/texpaint/texpaint.c | 311 ++ tools/quake2/extra/texpaint/texpaint.h | 88 + tools/quake2/extra/texpaint/texpaint.mak | 468 +++ tools/quake2/extra/texpaint/win_cam.c | 414 +++ tools/quake2/extra/texpaint/win_main.c | 496 +++ tools/quake2/extra/texpaint/win_pal.c | 257 ++ tools/quake2/extra/texpaint/win_skin.c | 946 +++++ 131 files changed, 52042 insertions(+) create mode 100644 tools/quake2/extra/COPYING.txt create mode 100644 tools/quake2/extra/Unpack/Unpack.dsp create mode 100644 tools/quake2/extra/Unpack/Unpack.dsw create mode 100644 tools/quake2/extra/Unpack/Unpack.java create mode 100644 tools/quake2/extra/bsp/bsp.mak create mode 100644 tools/quake2/extra/bsp/bspinfo3/bspinfo3.c create mode 100644 tools/quake2/extra/bsp/bspinfo3/makefile create mode 100644 tools/quake2/extra/bsp/qbsp3/brushbsp.c create mode 100644 tools/quake2/extra/bsp/qbsp3/csg.c create mode 100644 tools/quake2/extra/bsp/qbsp3/faces.c create mode 100644 tools/quake2/extra/bsp/qbsp3/gldraw.c create mode 100644 tools/quake2/extra/bsp/qbsp3/glfile.c create mode 100644 tools/quake2/extra/bsp/qbsp3/leakfile.c create mode 100644 tools/quake2/extra/bsp/qbsp3/makefile create mode 100644 tools/quake2/extra/bsp/qbsp3/map.c create mode 100644 tools/quake2/extra/bsp/qbsp3/nodraw.c create mode 100644 tools/quake2/extra/bsp/qbsp3/portals.c create mode 100644 tools/quake2/extra/bsp/qbsp3/prtfile.c create mode 100644 tools/quake2/extra/bsp/qbsp3/qbsp.h create mode 100644 tools/quake2/extra/bsp/qbsp3/qbsp3.c create mode 100644 tools/quake2/extra/bsp/qbsp3/textures.c create mode 100644 tools/quake2/extra/bsp/qbsp3/tree.c create mode 100644 tools/quake2/extra/bsp/qbsp3/writebsp.c create mode 100644 tools/quake2/extra/bsp/qrad3/lightmap.c create mode 100644 tools/quake2/extra/bsp/qrad3/makefile create mode 100644 tools/quake2/extra/bsp/qrad3/patches.c create mode 100644 tools/quake2/extra/bsp/qrad3/qrad.h create mode 100644 tools/quake2/extra/bsp/qrad3/qrad3.c create mode 100644 tools/quake2/extra/bsp/qrad3/trace.c create mode 100644 tools/quake2/extra/bsp/qvis3/flow.c create mode 100644 tools/quake2/extra/bsp/qvis3/makefile create mode 100644 tools/quake2/extra/bsp/qvis3/qvis3.c create mode 100644 tools/quake2/extra/bsp/qvis3/vis.h create mode 100644 tools/quake2/extra/common/bspfile.c create mode 100644 tools/quake2/extra/common/bspfile.h create mode 100644 tools/quake2/extra/common/cmdlib.c create mode 100644 tools/quake2/extra/common/cmdlib.h create mode 100644 tools/quake2/extra/common/l3dslib.c create mode 100644 tools/quake2/extra/common/l3dslib.h create mode 100644 tools/quake2/extra/common/lbmlib.c create mode 100644 tools/quake2/extra/common/lbmlib.h create mode 100644 tools/quake2/extra/common/mathlib.c create mode 100644 tools/quake2/extra/common/mathlib.h create mode 100644 tools/quake2/extra/common/mdfour.c create mode 100644 tools/quake2/extra/common/mdfour.h create mode 100644 tools/quake2/extra/common/polylib.c create mode 100644 tools/quake2/extra/common/polylib.h create mode 100644 tools/quake2/extra/common/qfiles.h create mode 100644 tools/quake2/extra/common/scriplib.c create mode 100644 tools/quake2/extra/common/scriplib.h create mode 100644 tools/quake2/extra/common/threads.c create mode 100644 tools/quake2/extra/common/threads.h create mode 100644 tools/quake2/extra/common/trilib.c create mode 100644 tools/quake2/extra/common/trilib.h create mode 100644 tools/quake2/extra/qdata/anorms.h create mode 100644 tools/quake2/extra/qdata/images.c create mode 100644 tools/quake2/extra/qdata/makefile create mode 100644 tools/quake2/extra/qdata/models.c create mode 100644 tools/quake2/extra/qdata/qdata.c create mode 100644 tools/quake2/extra/qdata/qdata.dsp create mode 100644 tools/quake2/extra/qdata/qdata.dsw create mode 100644 tools/quake2/extra/qdata/qdata.h create mode 100644 tools/quake2/extra/qdata/qdata.mak create mode 100644 tools/quake2/extra/qdata/sprites.c create mode 100644 tools/quake2/extra/qdata/tables.c create mode 100644 tools/quake2/extra/qdata/video.c create mode 100644 tools/quake2/extra/qe4/brush.c create mode 100644 tools/quake2/extra/qe4/brush.h create mode 100644 tools/quake2/extra/qe4/bspfile.h create mode 100644 tools/quake2/extra/qe4/camera.c create mode 100644 tools/quake2/extra/qe4/camera.h create mode 100644 tools/quake2/extra/qe4/cmdlib.c create mode 100644 tools/quake2/extra/qe4/cmdlib.h create mode 100644 tools/quake2/extra/qe4/csg.c create mode 100644 tools/quake2/extra/qe4/drag.c create mode 100644 tools/quake2/extra/qe4/eclass.c create mode 100644 tools/quake2/extra/qe4/entity.c create mode 100644 tools/quake2/extra/qe4/entity.h create mode 100644 tools/quake2/extra/qe4/entityw.h create mode 100644 tools/quake2/extra/qe4/glingr.h create mode 100644 tools/quake2/extra/qe4/icon1.ico create mode 100644 tools/quake2/extra/qe4/lbmlib.c create mode 100644 tools/quake2/extra/qe4/lbmlib.h create mode 100644 tools/quake2/extra/qe4/makefile create mode 100644 tools/quake2/extra/qe4/map.c create mode 100644 tools/quake2/extra/qe4/map.h create mode 100644 tools/quake2/extra/qe4/mathlib.c create mode 100644 tools/quake2/extra/qe4/mathlib.h create mode 100644 tools/quake2/extra/qe4/mru.c create mode 100644 tools/quake2/extra/qe4/mru.h create mode 100644 tools/quake2/extra/qe4/parse.c create mode 100644 tools/quake2/extra/qe4/parse.h create mode 100644 tools/quake2/extra/qe4/points.c create mode 100644 tools/quake2/extra/qe4/q.bmp create mode 100644 tools/quake2/extra/qe4/qe3.c create mode 100644 tools/quake2/extra/qe4/qe3.h create mode 100644 tools/quake2/extra/qe4/qe4.mak create mode 100644 tools/quake2/extra/qe4/qedefs.h create mode 100644 tools/quake2/extra/qe4/qfiles.h create mode 100644 tools/quake2/extra/qe4/resource.h create mode 100644 tools/quake2/extra/qe4/select.c create mode 100644 tools/quake2/extra/qe4/select.h create mode 100644 tools/quake2/extra/qe4/textures.c create mode 100644 tools/quake2/extra/qe4/textures.h create mode 100644 tools/quake2/extra/qe4/toolbar1.bmp create mode 100644 tools/quake2/extra/qe4/vertsel.c create mode 100644 tools/quake2/extra/qe4/view.h create mode 100644 tools/quake2/extra/qe4/win_cam.c create mode 100644 tools/quake2/extra/qe4/win_dlg.c create mode 100644 tools/quake2/extra/qe4/win_ent.c create mode 100644 tools/quake2/extra/qe4/win_main.c create mode 100644 tools/quake2/extra/qe4/win_qe3.aps create mode 100644 tools/quake2/extra/qe4/win_qe3.c create mode 100644 tools/quake2/extra/qe4/win_qe3.rc create mode 100644 tools/quake2/extra/qe4/win_xy.c create mode 100644 tools/quake2/extra/qe4/win_z.c create mode 100644 tools/quake2/extra/qe4/xy.c create mode 100644 tools/quake2/extra/qe4/xy.h create mode 100644 tools/quake2/extra/qe4/z.c create mode 100644 tools/quake2/extra/qe4/z.h create mode 100644 tools/quake2/extra/texpaint/docs.txt create mode 100644 tools/quake2/extra/texpaint/resource.h create mode 100644 tools/quake2/extra/texpaint/texmake.aps create mode 100644 tools/quake2/extra/texpaint/texmake.rc create mode 100644 tools/quake2/extra/texpaint/texpaint.c create mode 100644 tools/quake2/extra/texpaint/texpaint.h create mode 100644 tools/quake2/extra/texpaint/texpaint.mak create mode 100644 tools/quake2/extra/texpaint/win_cam.c create mode 100644 tools/quake2/extra/texpaint/win_main.c create mode 100644 tools/quake2/extra/texpaint/win_pal.c create mode 100644 tools/quake2/extra/texpaint/win_skin.c diff --git a/tools/quake2/extra/COPYING.txt b/tools/quake2/extra/COPYING.txt new file mode 100644 index 00000000..98443f35 --- /dev/null +++ b/tools/quake2/extra/COPYING.txt @@ -0,0 +1,281 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/tools/quake2/extra/Unpack/Unpack.dsp b/tools/quake2/extra/Unpack/Unpack.dsp new file mode 100644 index 00000000..89bea7ca --- /dev/null +++ b/tools/quake2/extra/Unpack/Unpack.dsp @@ -0,0 +1,72 @@ +# Microsoft Developer Studio Project File - Name="Unpack" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Java Virtual Machine Java Project" 0x0809 + +CFG=Unpack - Java Virtual Machine Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Unpack.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Unpack.mak" CFG="Unpack - Java Virtual Machine Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Unpack - Java Virtual Machine Release" (based on\ + "Java Virtual Machine Java Project") +!MESSAGE "Unpack - Java Virtual Machine Debug" (based on\ + "Java Virtual Machine Java Project") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +JAVA=jvc.exe + +!IF "$(CFG)" == "Unpack - Java Virtual Machine Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "" +# PROP Target_Dir "" +# ADD BASE JAVA /O +# ADD JAVA /O + +!ELSEIF "$(CFG)" == "Unpack - Java Virtual Machine Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "" +# PROP Target_Dir "" +# ADD BASE JAVA /g +# ADD JAVA /g + +!ENDIF + +# Begin Target + +# Name "Unpack - Java Virtual Machine Release" +# Name "Unpack - Java Virtual Machine Debug" +# Begin Source File + +SOURCE=.\Unpack.java +# End Source File +# End Target +# End Project diff --git a/tools/quake2/extra/Unpack/Unpack.dsw b/tools/quake2/extra/Unpack/Unpack.dsw new file mode 100644 index 00000000..29aef98e --- /dev/null +++ b/tools/quake2/extra/Unpack/Unpack.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Unpack"=.\Unpack.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/tools/quake2/extra/Unpack/Unpack.java b/tools/quake2/extra/Unpack/Unpack.java new file mode 100644 index 00000000..a18e72fa --- /dev/null +++ b/tools/quake2/extra/Unpack/Unpack.java @@ -0,0 +1,198 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +/* + * Unpack -- a completely non-object oriented utility... + * + */ + +import java.io.*; + +class Unpack { + static final int IDPAKHEADER = (('K'<<24)+('C'<<16)+('A'<<8)+'P'); + + static int intSwap(int i) { + int a, b, c, d; + + a = i & 255; + b = (i >> 8) & 255; + c = (i >> 16) & 255; + d = (i >> 24) & 255; + + return (a << 24) + (b << 16) + (c << 8) + d; + } + + static boolean patternMatch (String pattern, String s) { + int index; + int remaining; + + if (pattern.equals(s)) { + return true; + } + + // fairly lame single wildcard matching + index = pattern.indexOf('*'); + if (index == -1) { + return false; + } + if (!pattern.regionMatches(0, s, 0, index)) { + return false; + } + + index += 1; // skip the * + remaining = pattern.length() - index; + if (s.length() < remaining) { + return false; + } + + if (!pattern.regionMatches(index, s, s.length()-remaining, remaining)) { + return false; + } + + return true; + } + + static void usage() { + System.out.println ("Usage: unpack "); + System.out.println (" or: unpack -list "); + System.out.println (" may contain a single * wildcard"); + System.exit (1); + } + + public static void main (String[] args) { + int ident; + int dirofs; + int dirlen; + int i; + int numLumps; + byte[] name = new byte[56]; + String nameString; + int filepos; + int filelen; + RandomAccessFile readLump; + DataInputStream directory; + String pakName; + String pattern; + + if (args.length == 2) { + if (!args[0].equals("-list")) { + usage(); + } + pakName = args[1]; + pattern = null; + } else if (args.length == 3) { + pakName = args[0]; + pattern = args[1]; + } else { + pakName = null; + pattern = null; + usage (); + } + + try { + // one stream to read the directory + directory = new DataInputStream(new FileInputStream(pakName)); + + // another to read lumps + readLump = new RandomAccessFile(pakName, "r"); + + // read the header + ident = intSwap(directory.readInt()); + dirofs = intSwap(directory.readInt()); + dirlen = intSwap(directory.readInt()); + + if (ident != IDPAKHEADER) { + System.out.println ( pakName + " is not a pakfile."); + System.exit (1); + } + + // read the directory + directory.skipBytes (dirofs - 12); + numLumps = dirlen / 64; + + System.out.println (numLumps + " lumps in " + pakName); + + for (i = 0 ; i < numLumps ; i++) { + directory.readFully(name); + filepos = intSwap(directory.readInt()); + filelen = intSwap(directory.readInt()); + + nameString = new String (name, 0); + // chop to the first 0 byte + nameString = nameString.substring (0, nameString.indexOf(0)); + + if (pattern == null) { + // listing mode + System.out.println (nameString + " : " + filelen + "bytes"); + } else if (patternMatch (pattern, nameString) ) { + File writeFile; + DataOutputStream writeLump; + byte[] buffer = new byte[filelen]; + StringBuffer fixedString; + String finalName; + int index; + + System.out.println ("Unpaking " + nameString + " " + filelen + + " bytes"); + + // load the lump + readLump.seek(filepos); + readLump.readFully(buffer); + + // quake uses forward slashes, but java requires + // they only by the host's seperator, which + // varies from win to unix + fixedString = new StringBuffer (args[2] + File.separator + nameString); + for (index = 0 ; index < fixedString.length() ; index++) { + if (fixedString.charAt(index) == '/') { + fixedString.setCharAt(index, File.separatorChar); + } + } + finalName = fixedString.toString (); + + index = finalName.lastIndexOf(File.separatorChar); + if (index != -1) { + String finalPath; + File writePath; + + finalPath = finalName.substring(0, index); + writePath = new File (finalPath); + writePath.mkdirs(); + } + + writeFile = new File (finalName); + writeLump = new DataOutputStream ( new FileOutputStream(writeFile) ); + writeLump.write(buffer); + writeLump.close(); + + } + } + + readLump.close(); + directory.close(); + + } catch (IOException e) { + System.out.println ( e.toString() ); + } + } + +} diff --git a/tools/quake2/extra/bsp/bsp.mak b/tools/quake2/extra/bsp/bsp.mak new file mode 100644 index 00000000..17218de7 --- /dev/null +++ b/tools/quake2/extra/bsp/bsp.mak @@ -0,0 +1,1776 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=bspinfo3 - Win32 Debug +!MESSAGE No configuration specified. Defaulting to bspinfo3 - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "bsp - Win32 Release" && "$(CFG)" != "bsp - Win32 Debug" &&\ + "$(CFG)" != "qbsp3 - Win32 Release" && "$(CFG)" != "qbsp3 - Win32 Debug" &&\ + "$(CFG)" != "qvis3 - Win32 Release" && "$(CFG)" != "qvis3 - Win32 Debug" &&\ + "$(CFG)" != "qrad3 - Win32 Release" && "$(CFG)" != "qrad3 - Win32 Debug" &&\ + "$(CFG)" != "bspinfo3 - Win32 Release" && "$(CFG)" != "bspinfo3 - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bsp.mak" CFG="bspinfo3 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bsp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "bsp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "qbsp3 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "qbsp3 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "qvis3 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "qvis3 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "qrad3 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "qrad3 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "bspinfo3 - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "bspinfo3 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "bspinfo3 - Win32 Debug" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bsp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : + +CLEAN : + -@erase + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/bsp.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/bsp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/bsp.pdb" /machine:I386\ + /out:"$(OUTDIR)/bsp.exe" +LINK32_OBJS= \ + + +!ELSEIF "$(CFG)" == "bsp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : + +CLEAN : + -@erase + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/bsp.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/bsp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/bsp.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/bsp.exe" +LINK32_OBJS= \ + + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "qbsp3\Release" +# PROP BASE Intermediate_Dir "qbsp3\Release" +# PROP BASE Target_Dir "qbsp3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "qbsp3\Release" +# PROP Intermediate_Dir "qbsp3\Release" +# PROP Target_Dir "qbsp3" +OUTDIR=.\qbsp3\Release +INTDIR=.\qbsp3\Release + +ALL : "$(OUTDIR)\qbsp3.exe" + +CLEAN : + -@erase "$(INTDIR)\brushbsp.obj" + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\csg.obj" + -@erase "$(INTDIR)\faces.obj" + -@erase "$(INTDIR)\gldraw.obj" + -@erase "$(INTDIR)\glfile.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\leakfile.obj" + -@erase "$(INTDIR)\map.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\polylib.obj" + -@erase "$(INTDIR)\portals.obj" + -@erase "$(INTDIR)\prtfile.obj" + -@erase "$(INTDIR)\qbsp3.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\textures.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\tree.obj" + -@erase "$(INTDIR)\writebsp.obj" + -@erase "$(OUTDIR)\qbsp3.exe" + -@erase "$(OUTDIR)\qbsp3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/qbsp3.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\qbsp3\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qbsp3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/qbsp3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qbsp3.exe" +LINK32_OBJS= \ + "$(INTDIR)\brushbsp.obj" \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\csg.obj" \ + "$(INTDIR)\faces.obj" \ + "$(INTDIR)\gldraw.obj" \ + "$(INTDIR)\glfile.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\leakfile.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\polylib.obj" \ + "$(INTDIR)\portals.obj" \ + "$(INTDIR)\prtfile.obj" \ + "$(INTDIR)\qbsp3.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\textures.obj" \ + "$(INTDIR)\threads.obj" \ + "$(INTDIR)\tree.obj" \ + "$(INTDIR)\writebsp.obj" + +"$(OUTDIR)\qbsp3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "qbsp3\Debug" +# PROP BASE Intermediate_Dir "qbsp3\Debug" +# PROP BASE Target_Dir "qbsp3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "qbsp3\Debug" +# PROP Intermediate_Dir "qbsp3\Debug" +# PROP Target_Dir "qbsp3" +OUTDIR=.\qbsp3\Debug +INTDIR=.\qbsp3\Debug + +ALL : "$(OUTDIR)\qbsp3.exe" + +CLEAN : + -@erase "$(INTDIR)\brushbsp.obj" + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\csg.obj" + -@erase "$(INTDIR)\faces.obj" + -@erase "$(INTDIR)\gldraw.obj" + -@erase "$(INTDIR)\glfile.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\leakfile.obj" + -@erase "$(INTDIR)\map.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\polylib.obj" + -@erase "$(INTDIR)\portals.obj" + -@erase "$(INTDIR)\prtfile.obj" + -@erase "$(INTDIR)\qbsp3.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\textures.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\tree.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\writebsp.obj" + -@erase "$(OUTDIR)\qbsp3.exe" + -@erase "$(OUTDIR)\qbsp3.ilk" + -@erase "$(OUTDIR)\qbsp3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/qbsp3.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\qbsp3\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qbsp3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/qbsp3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qbsp3.exe" +LINK32_OBJS= \ + "$(INTDIR)\brushbsp.obj" \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\csg.obj" \ + "$(INTDIR)\faces.obj" \ + "$(INTDIR)\gldraw.obj" \ + "$(INTDIR)\glfile.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\leakfile.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\polylib.obj" \ + "$(INTDIR)\portals.obj" \ + "$(INTDIR)\prtfile.obj" \ + "$(INTDIR)\qbsp3.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\textures.obj" \ + "$(INTDIR)\threads.obj" \ + "$(INTDIR)\tree.obj" \ + "$(INTDIR)\writebsp.obj" + +"$(OUTDIR)\qbsp3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qvis3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "qvis3\Release" +# PROP BASE Intermediate_Dir "qvis3\Release" +# PROP BASE Target_Dir "qvis3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "qvis3\Release" +# PROP Intermediate_Dir "qvis3\Release" +# PROP Target_Dir "qvis3" +OUTDIR=.\qvis3\Release +INTDIR=.\qvis3\Release + +ALL : "$(OUTDIR)\qvis3.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\flow.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\qvis3.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(OUTDIR)\qvis3.exe" + -@erase "$(OUTDIR)\qvis3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/qvis3.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\qvis3\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qvis3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/qvis3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qvis3.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\flow.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\qvis3.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\threads.obj" + +"$(OUTDIR)\qvis3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qvis3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "qvis3\Debug" +# PROP BASE Intermediate_Dir "qvis3\Debug" +# PROP BASE Target_Dir "qvis3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "qvis3\Debug" +# PROP Intermediate_Dir "qvis3\Debug" +# PROP Target_Dir "qvis3" +OUTDIR=.\qvis3\Debug +INTDIR=.\qvis3\Debug + +ALL : "$(OUTDIR)\qvis3.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\flow.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\qvis3.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\qvis3.exe" + -@erase "$(OUTDIR)\qvis3.ilk" + -@erase "$(OUTDIR)\qvis3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/qvis3.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\qvis3\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qvis3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/qvis3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qvis3.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\flow.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\qvis3.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\threads.obj" + +"$(OUTDIR)\qvis3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qrad3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "qrad3\Release" +# PROP BASE Intermediate_Dir "qrad3\Release" +# PROP BASE Target_Dir "qrad3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "qrad3\Release" +# PROP Intermediate_Dir "qrad3\Release" +# PROP Target_Dir "qrad3" +OUTDIR=.\qrad3\Release +INTDIR=.\qrad3\Release + +ALL : "$(OUTDIR)\qrad3.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\lightmap.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\patches.obj" + -@erase "$(INTDIR)\polylib.obj" + -@erase "$(INTDIR)\qrad3.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\trace.obj" + -@erase "$(OUTDIR)\qrad3.exe" + -@erase "$(OUTDIR)\qrad3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/qrad3.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\qrad3\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qrad3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/qrad3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qrad3.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\lightmap.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\patches.obj" \ + "$(INTDIR)\polylib.obj" \ + "$(INTDIR)\qrad3.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\threads.obj" \ + "$(INTDIR)\trace.obj" + +"$(OUTDIR)\qrad3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qrad3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "qrad3\Debug" +# PROP BASE Intermediate_Dir "qrad3\Debug" +# PROP BASE Target_Dir "qrad3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "qrad3\Debug" +# PROP Intermediate_Dir "qrad3\Debug" +# PROP Target_Dir "qrad3" +OUTDIR=.\qrad3\Debug +INTDIR=.\qrad3\Debug + +ALL : "$(OUTDIR)\qrad3.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\lightmap.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\patches.obj" + -@erase "$(INTDIR)\polylib.obj" + -@erase "$(INTDIR)\qrad3.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\trace.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\qrad3.exe" + -@erase "$(OUTDIR)\qrad3.ilk" + -@erase "$(OUTDIR)\qrad3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/qrad3.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\qrad3\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qrad3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/qrad3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/qrad3.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\lightmap.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\patches.obj" \ + "$(INTDIR)\polylib.obj" \ + "$(INTDIR)\qrad3.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\threads.obj" \ + "$(INTDIR)\trace.obj" + +"$(OUTDIR)\qrad3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "bspinfo3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "bspinfo3\Release" +# PROP BASE Intermediate_Dir "bspinfo3\Release" +# PROP BASE Target_Dir "bspinfo3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "bspinfo3\Release" +# PROP Intermediate_Dir "bspinfo3\Release" +# PROP Target_Dir "bspinfo3" +OUTDIR=.\bspinfo3\Release +INTDIR=.\bspinfo3\Release + +ALL : "$(OUTDIR)\bspinfo3.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\bspinfo3.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(OUTDIR)\bspinfo3.exe" + -@erase "$(OUTDIR)\bspinfo3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /Zd /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/bspinfo3.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\bspinfo3\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/bspinfo3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/bspinfo3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/bspinfo3.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\bspinfo3.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\scriplib.obj" + +"$(OUTDIR)\bspinfo3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "bspinfo3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "bspinfo3\Debug" +# PROP BASE Intermediate_Dir "bspinfo3\Debug" +# PROP BASE Target_Dir "bspinfo3" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "bspinfo3\Debug" +# PROP Intermediate_Dir "bspinfo3\Debug" +# PROP Target_Dir "bspinfo3" +OUTDIR=.\bspinfo3\Debug +INTDIR=.\bspinfo3\Debug + +ALL : "$(OUTDIR)\bspinfo3.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\bspinfo3.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\bspinfo3.exe" + -@erase "$(OUTDIR)\bspinfo3.ilk" + -@erase "$(OUTDIR)\bspinfo3.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MT /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/bspinfo3.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/"\ + /c +CPP_OBJS=.\bspinfo3\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/bspinfo3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib opengl32.lib glaux.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/bspinfo3.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/bspinfo3.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\bspinfo3.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\scriplib.obj" + +"$(OUTDIR)\bspinfo3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "bsp - Win32 Release" +# Name "bsp - Win32 Debug" + +!IF "$(CFG)" == "bsp - Win32 Release" + +!ELSEIF "$(CFG)" == "bsp - Win32 Debug" + +!ENDIF + +# End Target +################################################################################ +# Begin Target + +# Name "qbsp3 - Win32 Release" +# Name "qbsp3 - Win32 Debug" + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\writebsp.c + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +DEP_CPP_WRITE=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\writebsp.obj" : $(SOURCE) $(DEP_CPP_WRITE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +DEP_CPP_WRITE=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\writebsp.obj" : $(SOURCE) $(DEP_CPP_WRITE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\brushbsp.c +DEP_CPP_BRUSH=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\brushbsp.obj" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\csg.c +DEP_CPP_CSG_C=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\csg.obj" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\faces.c +DEP_CPP_FACES=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\faces.obj" : $(SOURCE) $(DEP_CPP_FACES) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\gldraw.c + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +DEP_CPP_GLDRA=\ + ".\qbsp3\qbsp.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\gldraw.obj" : $(SOURCE) $(DEP_CPP_GLDRA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +DEP_CPP_GLDRA=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\gldraw.obj" : $(SOURCE) $(DEP_CPP_GLDRA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\glfile.c + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +DEP_CPP_GLFIL=\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\glfile.obj" : $(SOURCE) $(DEP_CPP_GLFIL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +DEP_CPP_GLFIL=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\glfile.obj" : $(SOURCE) $(DEP_CPP_GLFIL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\leakfile.c + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +DEP_CPP_LEAKF=\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\leakfile.obj" : $(SOURCE) $(DEP_CPP_LEAKF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +DEP_CPP_LEAKF=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\leakfile.obj" : $(SOURCE) $(DEP_CPP_LEAKF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\map.c +DEP_CPP_MAP_C=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\map.obj" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\portals.c +DEP_CPP_PORTA=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\portals.obj" : $(SOURCE) $(DEP_CPP_PORTA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\prtfile.c +DEP_CPP_PRTFI=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\prtfile.obj" : $(SOURCE) $(DEP_CPP_PRTFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\qbsp.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\qbsp3.c +DEP_CPP_QBSP3=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\qbsp3.obj" : $(SOURCE) $(DEP_CPP_QBSP3) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\textures.c +DEP_CPP_TEXTU=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\textures.obj" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qbsp3\tree.c +DEP_CPP_TREE_=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + "..\common\threads.h"\ + ".\qbsp3\qbsp.h"\ + + +"$(INTDIR)\tree.obj" : $(SOURCE) $(DEP_CPP_TREE_) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\threads.c +DEP_CPP_THREA=\ + "..\common\cmdlib.h"\ + "..\common\threads.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\threads.obj" : $(SOURCE) $(DEP_CPP_THREA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.c +DEP_CPP_CMDLI=\ + "..\common\cmdlib.h"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\lbmlib.c +DEP_CPP_LBMLI=\ + "..\common\cmdlib.h"\ + "..\common\lbmlib.h"\ + + +"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.c +DEP_CPP_MATHL=\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\polylib.c +DEP_CPP_POLYL=\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + + +"$(INTDIR)\polylib.obj" : $(SOURCE) $(DEP_CPP_POLYL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\scriplib.c +DEP_CPP_SCRIP=\ + "..\common\cmdlib.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.c +DEP_CPP_BSPFI=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\bspfile.obj" : $(SOURCE) $(DEP_CPP_BSPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\threads.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\lbmlib.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\polylib.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\scriplib.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\qfiles.h + +!IF "$(CFG)" == "qbsp3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qbsp3 - Win32 Debug" + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "qvis3 - Win32 Release" +# Name "qvis3 - Win32 Debug" + +!IF "$(CFG)" == "qvis3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qvis3 - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\qvis3\vis.h + +!IF "$(CFG)" == "qvis3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qvis3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qvis3\qvis3.c +DEP_CPP_QVIS3=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + "..\common\threads.h"\ + ".\qvis3\vis.h"\ + + +"$(INTDIR)\qvis3.obj" : $(SOURCE) $(DEP_CPP_QVIS3) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qvis3\flow.c +DEP_CPP_FLOW_=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + ".\qvis3\vis.h"\ + + +"$(INTDIR)\flow.obj" : $(SOURCE) $(DEP_CPP_FLOW_) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.c +DEP_CPP_CMDLI=\ + "..\common\cmdlib.h"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.c +DEP_CPP_MATHL=\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\scriplib.c +DEP_CPP_SCRIP=\ + "..\common\cmdlib.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\threads.c +DEP_CPP_THREA=\ + "..\common\cmdlib.h"\ + "..\common\threads.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\threads.obj" : $(SOURCE) $(DEP_CPP_THREA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.c +DEP_CPP_BSPFI=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\bspfile.obj" : $(SOURCE) $(DEP_CPP_BSPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "qrad3 - Win32 Release" +# Name "qrad3 - Win32 Debug" + +!IF "$(CFG)" == "qrad3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qrad3 - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\qrad3\patches.c +DEP_CPP_PATCH=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\threads.h"\ + ".\qrad3\qrad.h"\ + + +"$(INTDIR)\patches.obj" : $(SOURCE) $(DEP_CPP_PATCH) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qrad3\lightmap.c +DEP_CPP_LIGHT=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\threads.h"\ + ".\qrad3\qrad.h"\ + + +"$(INTDIR)\lightmap.obj" : $(SOURCE) $(DEP_CPP_LIGHT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qrad3\qrad.h + +!IF "$(CFG)" == "qrad3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qrad3 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qrad3\qrad3.c +DEP_CPP_QRAD3=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + "..\common\qfiles.h"\ + "..\common\threads.h"\ + ".\qrad3\qrad.h"\ + + +"$(INTDIR)\qrad3.obj" : $(SOURCE) $(DEP_CPP_QRAD3) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qrad3\trace.c +DEP_CPP_TRACE=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + + +"$(INTDIR)\trace.obj" : $(SOURCE) $(DEP_CPP_TRACE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\threads.c +DEP_CPP_THREA=\ + "..\common\cmdlib.h"\ + "..\common\threads.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\threads.obj" : $(SOURCE) $(DEP_CPP_THREA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.c +DEP_CPP_CMDLI=\ + "..\common\cmdlib.h"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.c +DEP_CPP_MATHL=\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\polylib.c +DEP_CPP_POLYL=\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\polylib.h"\ + + +"$(INTDIR)\polylib.obj" : $(SOURCE) $(DEP_CPP_POLYL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\scriplib.c +DEP_CPP_SCRIP=\ + "..\common\cmdlib.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.c +DEP_CPP_BSPFI=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\bspfile.obj" : $(SOURCE) $(DEP_CPP_BSPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\lbmlib.c +DEP_CPP_LBMLI=\ + "..\common\cmdlib.h"\ + "..\common\lbmlib.h"\ + + +"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "bspinfo3 - Win32 Release" +# Name "bspinfo3 - Win32 Debug" + +!IF "$(CFG)" == "bspinfo3 - Win32 Release" + +!ELSEIF "$(CFG)" == "bspinfo3 - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\bspinfo3\bspinfo3.c +DEP_CPP_BSPIN=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + + +"$(INTDIR)\bspinfo3.obj" : $(SOURCE) $(DEP_CPP_BSPIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.c +DEP_CPP_MATHL=\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.c +DEP_CPP_CMDLI=\ + "..\common\cmdlib.h"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.c +DEP_CPP_BSPFI=\ + "..\common\bspfile.h"\ + "..\common\cmdlib.h"\ + "..\common\mathlib.h"\ + "..\common\qfiles.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\bspfile.obj" : $(SOURCE) $(DEP_CPP_BSPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\scriplib.c +DEP_CPP_SCRIP=\ + "..\common\cmdlib.h"\ + "..\common\scriplib.h"\ + + +"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/tools/quake2/extra/bsp/bspinfo3/bspinfo3.c b/tools/quake2/extra/bsp/bspinfo3/bspinfo3.c new file mode 100644 index 00000000..75a414f3 --- /dev/null +++ b/tools/quake2/extra/bsp/bspinfo3/bspinfo3.c @@ -0,0 +1,56 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "cmdlib.h" +#include "mathlib.h" +#include "bspfile.h" + +void main (int argc, char **argv) +{ + int i; + char source[1024]; + int size; + FILE *f; + + if (argc == 1) + Error ("usage: bspinfo bspfile [bspfiles]"); + + for (i=1 ; i /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i + +$(ODIR)/cmdlib.o : ../../common/cmdlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/scriplib.o : ../../common/scriplib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/bspfile.o : ../../common/bspfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i diff --git a/tools/quake2/extra/bsp/qbsp3/brushbsp.c b/tools/quake2/extra/bsp/qbsp3/brushbsp.c new file mode 100644 index 00000000..a111bd3b --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/brushbsp.c @@ -0,0 +1,1330 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + + +int c_nodes; +int c_nonvis; +int c_active_brushes; + +// if a brush just barely pokes onto the other side, +// let it slide by without chopping +#define PLANESIDE_EPSILON 0.001 +//0.1 + +#define PSIDE_FRONT 1 +#define PSIDE_BACK 2 +#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK) +#define PSIDE_FACING 4 + + +void FindBrushInTree (node_t *node, int brushnum) +{ + bspbrush_t *b; + + if (node->planenum == PLANENUM_LEAF) + { + for (b=node->brushlist ; b ; b=b->next) + if (b->original->brushnum == brushnum) + printf ("here\n"); + return; + } + FindBrushInTree (node->children[0], brushnum); + FindBrushInTree (node->children[1], brushnum); +} + +//================================================== + +/* +================ +DrawBrushList +================ +*/ +void DrawBrushList (bspbrush_t *brush, node_t *node) +{ + int i; + side_t *s; + + GLS_BeginScene (); + for ( ; brush ; brush=brush->next) + { + for (i=0 ; inumsides ; i++) + { + s = &brush->sides[i]; + if (!s->winding) + continue; + if (s->texinfo == TEXINFO_NODE) + GLS_Winding (s->winding, 1); + else if (!s->visible) + GLS_Winding (s->winding, 2); + else + GLS_Winding (s->winding, 0); + } + } + GLS_EndScene (); +} + +/* +================ +WriteBrushList +================ +*/ +void WriteBrushList (char *name, bspbrush_t *brush, qboolean onlyvis) +{ + int i; + side_t *s; + FILE *f; + + qprintf ("writing %s\n", name); + f = SafeOpenWrite (name); + + for ( ; brush ; brush=brush->next) + { + for (i=0 ; inumsides ; i++) + { + s = &brush->sides[i]; + if (!s->winding) + continue; + if (onlyvis && !s->visible) + continue; + OutputWinding (brush->sides[i].winding, f); + } + } + + fclose (f); +} + +void PrintBrush (bspbrush_t *brush) +{ + int i; + + printf ("brush: %p\n", brush); + for (i=0;inumsides ; i++) + { + pw(brush->sides[i].winding); + printf ("\n"); + } +} + +/* +================== +BoundBrush + +Sets the mins/maxs based on the windings +================== +*/ +void BoundBrush (bspbrush_t *brush) +{ + int i, j; + winding_t *w; + + ClearBounds (brush->mins, brush->maxs); + for (i=0 ; inumsides ; i++) + { + w = brush->sides[i].winding; + if (!w) + continue; + for (j=0 ; jnumpoints ; j++) + AddPointToBounds (w->p[j], brush->mins, brush->maxs); + } +} + +/* +================== +CreateBrushWindings + +================== +*/ +void CreateBrushWindings (bspbrush_t *brush) +{ + int i, j; + winding_t *w; + side_t *side; + plane_t *plane; + + for (i=0 ; inumsides ; i++) + { + side = &brush->sides[i]; + plane = &mapplanes[side->planenum]; + w = BaseWindingForPlane (plane->normal, plane->dist); + for (j=0 ; jnumsides && w; j++) + { + if (i == j) + continue; + if (brush->sides[j].bevel) + continue; + plane = &mapplanes[brush->sides[j].planenum^1]; + ChopWindingInPlace (&w, plane->normal, plane->dist, 0); //CLIP_EPSILON); + } + + side->winding = w; + } + + BoundBrush (brush); +} + +/* +================== +BrushFromBounds + +Creates a new axial brush +================== +*/ +bspbrush_t *BrushFromBounds (vec3_t mins, vec3_t maxs) +{ + bspbrush_t *b; + int i; + vec3_t normal; + vec_t dist; + + b = AllocBrush (6); + b->numsides = 6; + for (i=0 ; i<3 ; i++) + { + VectorClear (normal); + normal[i] = 1; + dist = maxs[i]; + b->sides[i].planenum = FindFloatPlane (normal, dist); + + normal[i] = -1; + dist = -mins[i]; + b->sides[3+i].planenum = FindFloatPlane (normal, dist); + } + + CreateBrushWindings (b); + + return b; +} + +/* +================== +BrushVolume + +================== +*/ +vec_t BrushVolume (bspbrush_t *brush) +{ + int i; + winding_t *w; + vec3_t corner; + vec_t d, area, volume; + plane_t *plane; + + if (!brush) + return 0; + + // grab the first valid point as the corner + + w = NULL; + for (i=0 ; inumsides ; i++) + { + w = brush->sides[i].winding; + if (w) + break; + } + if (!w) + return 0; + VectorCopy (w->p[0], corner); + + // make tetrahedrons to all other faces + + volume = 0; + for ( ; inumsides ; i++) + { + w = brush->sides[i].winding; + if (!w) + continue; + plane = &mapplanes[brush->sides[i].planenum]; + d = -(DotProduct (corner, plane->normal) - plane->dist); + area = WindingArea (w); + volume += d*area; + } + + volume /= 3; + return volume; +} + +/* +================ +CountBrushList +================ +*/ +int CountBrushList (bspbrush_t *brushes) +{ + int c; + + c = 0; + for ( ; brushes ; brushes = brushes->next) + c++; + return c; +} + +/* +================ +AllocTree +================ +*/ +tree_t *AllocTree (void) +{ + tree_t *tree; + + tree = malloc(sizeof(*tree)); + memset (tree, 0, sizeof(*tree)); + ClearBounds (tree->mins, tree->maxs); + + return tree; +} + +/* +================ +AllocNode +================ +*/ +node_t *AllocNode (void) +{ + node_t *node; + + node = malloc(sizeof(*node)); + memset (node, 0, sizeof(*node)); + + return node; +} + + +/* +================ +AllocBrush +================ +*/ +bspbrush_t *AllocBrush (int numsides) +{ + bspbrush_t *bb; + int c; + + c = (int)&(((bspbrush_t *)0)->sides[numsides]); + bb = malloc(c); + memset (bb, 0, c); + if (numthreads == 1) + c_active_brushes++; + return bb; +} + +/* +================ +FreeBrush +================ +*/ +void FreeBrush (bspbrush_t *brushes) +{ + int i; + + for (i=0 ; inumsides ; i++) + if (brushes->sides[i].winding) + FreeWinding(brushes->sides[i].winding); + free (brushes); + if (numthreads == 1) + c_active_brushes--; +} + + +/* +================ +FreeBrushList +================ +*/ +void FreeBrushList (bspbrush_t *brushes) +{ + bspbrush_t *next; + + for ( ; brushes ; brushes = next) + { + next = brushes->next; + + FreeBrush (brushes); + } +} + +/* +================== +CopyBrush + +Duplicates the brush, the sides, and the windings +================== +*/ +bspbrush_t *CopyBrush (bspbrush_t *brush) +{ + bspbrush_t *newbrush; + int size; + int i; + + size = (int)&(((bspbrush_t *)0)->sides[brush->numsides]); + + newbrush = AllocBrush (brush->numsides); + memcpy (newbrush, brush, size); + + for (i=0 ; inumsides ; i++) + { + if (brush->sides[i].winding) + newbrush->sides[i].winding = CopyWinding (brush->sides[i].winding); + } + + return newbrush; +} + + +/* +================== +PointInLeaf + +================== +*/ +node_t *PointInLeaf (node_t *node, vec3_t point) +{ + vec_t d; + plane_t *plane; + + while (node->planenum != PLANENUM_LEAF) + { + plane = &mapplanes[node->planenum]; + d = DotProduct (point, plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return node; +} + +//======================================================== + +/* +============== +BoxOnPlaneSide + +Returns PSIDE_FRONT, PSIDE_BACK, or PSIDE_BOTH +============== +*/ +int BoxOnPlaneSide (vec3_t mins, vec3_t maxs, plane_t *plane) +{ + int side; + int i; + vec3_t corners[2]; + vec_t dist1, dist2; + + // axial planes are easy + if (plane->type < 3) + { + side = 0; + if (maxs[plane->type] > plane->dist+PLANESIDE_EPSILON) + side |= PSIDE_FRONT; + if (mins[plane->type] < plane->dist-PLANESIDE_EPSILON) + side |= PSIDE_BACK; + return side; + } + + // create the proper leading and trailing verts for the box + + for (i=0 ; i<3 ; i++) + { + if (plane->normal[i] < 0) + { + corners[0][i] = mins[i]; + corners[1][i] = maxs[i]; + } + else + { + corners[1][i] = mins[i]; + corners[0][i] = maxs[i]; + } + } + + dist1 = DotProduct (plane->normal, corners[0]) - plane->dist; + dist2 = DotProduct (plane->normal, corners[1]) - plane->dist; + side = 0; + if (dist1 >= PLANESIDE_EPSILON) + side = PSIDE_FRONT; + if (dist2 < PLANESIDE_EPSILON) + side |= PSIDE_BACK; + + return side; +} + +/* +============ +QuickTestBrushToPlanenum + +============ +*/ +int QuickTestBrushToPlanenum (bspbrush_t *brush, int planenum, int *numsplits) +{ + int i, num; + plane_t *plane; + int s; + + *numsplits = 0; + + // if the brush actually uses the planenum, + // we can tell the side for sure + for (i=0 ; inumsides ; i++) + { + num = brush->sides[i].planenum; + if (num >= 0x10000) + Error ("bad planenum"); + if (num == planenum) + return PSIDE_BACK|PSIDE_FACING; + if (num == (planenum ^ 1) ) + return PSIDE_FRONT|PSIDE_FACING; + } + + // box on plane side + plane = &mapplanes[planenum]; + s = BoxOnPlaneSide (brush->mins, brush->maxs, plane); + + // if both sides, count the visible faces split + if (s == PSIDE_BOTH) + { + *numsplits += 3; + } + + return s; +} + +/* +============ +TestBrushToPlanenum + +============ +*/ +int TestBrushToPlanenum (bspbrush_t *brush, int planenum, + int *numsplits, qboolean *hintsplit, int *epsilonbrush) +{ + int i, j, num; + plane_t *plane; + int s; + winding_t *w; + vec_t d, d_front, d_back; + int front, back; + + *numsplits = 0; + *hintsplit = false; + + // if the brush actually uses the planenum, + // we can tell the side for sure + for (i=0 ; inumsides ; i++) + { + num = brush->sides[i].planenum; + if (num >= 0x10000) + Error ("bad planenum"); + if (num == planenum) + return PSIDE_BACK|PSIDE_FACING; + if (num == (planenum ^ 1) ) + return PSIDE_FRONT|PSIDE_FACING; + } + + // box on plane side + plane = &mapplanes[planenum]; + s = BoxOnPlaneSide (brush->mins, brush->maxs, plane); + + if (s != PSIDE_BOTH) + return s; + +// if both sides, count the visible faces split + d_front = d_back = 0; + + for (i=0 ; inumsides ; i++) + { + if (brush->sides[i].texinfo == TEXINFO_NODE) + continue; // on node, don't worry about splits + if (!brush->sides[i].visible) + continue; // we don't care about non-visible + w = brush->sides[i].winding; + if (!w) + continue; + front = back = 0; + for (j=0 ; jnumpoints; j++) + { + d = DotProduct (w->p[j], plane->normal) - plane->dist; + if (d > d_front) + d_front = d; + if (d < d_back) + d_back = d; + + if (d > 0.1) // PLANESIDE_EPSILON) + front = 1; + if (d < -0.1) // PLANESIDE_EPSILON) + back = 1; + } + if (front && back) + { + if ( !(brush->sides[i].surf & SURF_SKIP) ) + { + (*numsplits)++; + if (brush->sides[i].surf & SURF_HINT) + *hintsplit = true; + } + } + } + + if ( (d_front > 0.0 && d_front < 1.0) + || (d_back < 0.0 && d_back > -1.0) ) + (*epsilonbrush)++; + +#if 0 + if (*numsplits == 0) + { // didn't really need to be split + if (front) + s = PSIDE_FRONT; + else if (back) + s = PSIDE_BACK; + else + s = 0; + } +#endif + + return s; +} + +//======================================================== + +/* +================ +WindingIsTiny + +Returns true if the winding would be crunched out of +existance by the vertex snapping. +================ +*/ +#define EDGE_LENGTH 0.2 +qboolean WindingIsTiny (winding_t *w) +{ +#if 0 + if (WindingArea (w) < 1) + return true; + return false; +#else + int i, j; + vec_t len; + vec3_t delta; + int edges; + + edges = 0; + for (i=0 ; inumpoints ; i++) + { + j = i == w->numpoints - 1 ? 0 : i+1; + VectorSubtract (w->p[j], w->p[i], delta); + len = VectorLength (delta); + if (len > EDGE_LENGTH) + { + if (++edges == 3) + return false; + } + } + return true; +#endif +} + +/* +================ +WindingIsHuge + +Returns true if the winding still has one of the points +from basewinding for plane +================ +*/ +qboolean WindingIsHuge (winding_t *w) +{ + int i, j; + + for (i=0 ; inumpoints ; i++) + { + for (j=0 ; j<3 ; j++) + if (w->p[i][j] < -8000 || w->p[i][j] > 8000) + return true; + } + return false; +} + +//============================================================ + +/* +================ +Leafnode +================ +*/ +void LeafNode (node_t *node, bspbrush_t *brushes) +{ + bspbrush_t *b; + int i; + + node->planenum = PLANENUM_LEAF; + node->contents = 0; + + for (b=brushes ; b ; b=b->next) + { + // if the brush is solid and all of its sides are on nodes, + // it eats everything + if (b->original->contents & CONTENTS_SOLID) + { + for (i=0 ; inumsides ; i++) + if (b->sides[i].texinfo != TEXINFO_NODE) + break; + if (i == b->numsides) + { + node->contents = CONTENTS_SOLID; + break; + } + } + node->contents |= b->original->contents; + } + + node->brushlist = brushes; +} + + +//============================================================ + +void CheckPlaneAgainstParents (int pnum, node_t *node) +{ + node_t *p; + + for (p=node->parent ; p ; p=p->parent) + { + if (p->planenum == pnum) + Error ("Tried parent"); + } +} + +qboolean CheckPlaneAgainstVolume (int pnum, node_t *node) +{ + bspbrush_t *front, *back; + qboolean good; + + SplitBrush (node->volume, pnum, &front, &back); + + good = (front && back); + + if (front) + FreeBrush (front); + if (back) + FreeBrush (back); + + return good; +} + +/* +================ +SelectSplitSide + +Using a hueristic, choses one of the sides out of the brushlist +to partition the brushes with. +Returns NULL if there are no valid planes to split with.. +================ +*/ +side_t *SelectSplitSide (bspbrush_t *brushes, node_t *node) +{ + int value, bestvalue; + bspbrush_t *brush, *test; + side_t *side, *bestside; + int i, j, pass, numpasses; + int pnum; + int s; + int front, back, both, facing, splits; + int bsplits; + int bestsplits; + int epsilonbrush; + qboolean hintsplit; + + bestside = NULL; + bestvalue = -99999; + bestsplits = 0; + + // the search order goes: visible-structural, visible-detail, + // nonvisible-structural, nonvisible-detail. + // If any valid plane is available in a pass, no further + // passes will be tried. + numpasses = 4; + for (pass = 0 ; pass < numpasses ; pass++) + { + for (brush = brushes ; brush ; brush=brush->next) + { + if ( (pass & 1) && !(brush->original->contents & CONTENTS_DETAIL) ) + continue; + if ( !(pass & 1) && (brush->original->contents & CONTENTS_DETAIL) ) + continue; + for (i=0 ; inumsides ; i++) + { + side = brush->sides + i; + if (side->bevel) + continue; // never use a bevel as a spliter + if (!side->winding) + continue; // nothing visible, so it can't split + if (side->texinfo == TEXINFO_NODE) + continue; // allready a node splitter + if (side->tested) + continue; // we allready have metrics for this plane + if (side->surf & SURF_SKIP) + continue; // skip surfaces are never chosen + if ( side->visible ^ (pass<2) ) + continue; // only check visible faces on first pass + + pnum = side->planenum; + pnum &= ~1; // allways use positive facing plane + + CheckPlaneAgainstParents (pnum, node); + + if (!CheckPlaneAgainstVolume (pnum, node)) + continue; // would produce a tiny volume + + front = 0; + back = 0; + both = 0; + facing = 0; + splits = 0; + epsilonbrush = 0; + + for (test = brushes ; test ; test=test->next) + { + s = TestBrushToPlanenum (test, pnum, &bsplits, &hintsplit, &epsilonbrush); + + splits += bsplits; + if (bsplits && (s&PSIDE_FACING) ) + Error ("PSIDE_FACING with splits"); + + test->testside = s; + // if the brush shares this face, don't bother + // testing that facenum as a splitter again + if (s & PSIDE_FACING) + { + facing++; + for (j=0 ; jnumsides ; j++) + { + if ( (test->sides[j].planenum&~1) == pnum) + test->sides[j].tested = true; + } + } + if (s & PSIDE_FRONT) + front++; + if (s & PSIDE_BACK) + back++; + if (s == PSIDE_BOTH) + both++; + } + + // give a value estimate for using this plane + + value = 5*facing - 5*splits - abs(front-back); +// value = -5*splits; +// value = 5*facing - 5*splits; + if (mapplanes[pnum].type < 3) + value+=5; // axial is better + value -= epsilonbrush*1000; // avoid! + + // never split a hint side except with another hint + if (hintsplit && !(side->surf & SURF_HINT) ) + value = -9999999; + + // save off the side test so we don't need + // to recalculate it when we actually seperate + // the brushes + if (value > bestvalue) + { + bestvalue = value; + bestside = side; + bestsplits = splits; + for (test = brushes ; test ; test=test->next) + test->side = test->testside; + } + } + } + + // if we found a good plane, don't bother trying any + // other passes + if (bestside) + { + if (pass > 1) + { + if (numthreads == 1) + c_nonvis++; + } + if (pass > 0) + node->detail_seperator = true; // not needed for vis + break; + } + } + + // + // clear all the tested flags we set + // + for (brush = brushes ; brush ; brush=brush->next) + { + for (i=0 ; inumsides ; i++) + brush->sides[i].tested = false; + } + + return bestside; +} + + +/* +================== +BrushMostlyOnSide + +================== +*/ +int BrushMostlyOnSide (bspbrush_t *brush, plane_t *plane) +{ + int i, j; + winding_t *w; + vec_t d, max; + int side; + + max = 0; + side = PSIDE_FRONT; + for (i=0 ; inumsides ; i++) + { + w = brush->sides[i].winding; + if (!w) + continue; + for (j=0 ; jnumpoints ; j++) + { + d = DotProduct (w->p[j], plane->normal) - plane->dist; + if (d > max) + { + max = d; + side = PSIDE_FRONT; + } + if (-d > max) + { + max = -d; + side = PSIDE_BACK; + } + } + } + return side; +} + +/* +================ +SplitBrush + +Generates two new brushes, leaving the original +unchanged +================ +*/ +void SplitBrush (bspbrush_t *brush, int planenum, + bspbrush_t **front, bspbrush_t **back) +{ + bspbrush_t *b[2]; + int i, j; + winding_t *w, *cw[2], *midwinding; + plane_t *plane, *plane2; + side_t *s, *cs; + float d, d_front, d_back; + + *front = *back = NULL; + plane = &mapplanes[planenum]; + + // check all points + d_front = d_back = 0; + for (i=0 ; inumsides ; i++) + { + w = brush->sides[i].winding; + if (!w) + continue; + for (j=0 ; jnumpoints ; j++) + { + d = DotProduct (w->p[j], plane->normal) - plane->dist; + if (d > 0 && d > d_front) + d_front = d; + if (d < 0 && d < d_back) + d_back = d; + } + } + if (d_front < 0.1) // PLANESIDE_EPSILON) + { // only on back + *back = CopyBrush (brush); + return; + } + if (d_back > -0.1) // PLANESIDE_EPSILON) + { // only on front + *front = CopyBrush (brush); + return; + } + + // create a new winding from the split plane + + w = BaseWindingForPlane (plane->normal, plane->dist); + for (i=0 ; inumsides && w ; i++) + { + plane2 = &mapplanes[brush->sides[i].planenum ^ 1]; + ChopWindingInPlace (&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON); + } + + if (!w || WindingIsTiny (w) ) + { // the brush isn't really split + int side; + + side = BrushMostlyOnSide (brush, plane); + if (side == PSIDE_FRONT) + *front = CopyBrush (brush); + if (side == PSIDE_BACK) + *back = CopyBrush (brush); + return; + } + + if (WindingIsHuge (w)) + { + qprintf ("WARNING: huge winding\n"); + } + + midwinding = w; + + // split it for real + + for (i=0 ; i<2 ; i++) + { + b[i] = AllocBrush (brush->numsides+1); + b[i]->original = brush->original; + } + + // split all the current windings + + for (i=0 ; inumsides ; i++) + { + s = &brush->sides[i]; + w = s->winding; + if (!w) + continue; + ClipWindingEpsilon (w, plane->normal, plane->dist, + 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]); + for (j=0 ; j<2 ; j++) + { + if (!cw[j]) + continue; +#if 0 + if (WindingIsTiny (cw[j])) + { + FreeWinding (cw[j]); + continue; + } +#endif + cs = &b[j]->sides[b[j]->numsides]; + b[j]->numsides++; + *cs = *s; +// cs->planenum = s->planenum; +// cs->texinfo = s->texinfo; +// cs->visible = s->visible; +// cs->original = s->original; + cs->winding = cw[j]; + cs->tested = false; + } + } + + + // see if we have valid polygons on both sides + + for (i=0 ; i<2 ; i++) + { + BoundBrush (b[i]); + for (j=0 ; j<3 ; j++) + { + if (b[i]->mins[j] < -4096 || b[i]->maxs[j] > 4096) + { + qprintf ("bogus brush after clip\n"); + break; + } + } + + if (b[i]->numsides < 3 || j < 3) + { + FreeBrush (b[i]); + b[i] = NULL; + } + } + + if ( !(b[0] && b[1]) ) + { + if (!b[0] && !b[1]) + qprintf ("split removed brush\n"); + else + qprintf ("split not on both sides\n"); + if (b[0]) + { + FreeBrush (b[0]); + *front = CopyBrush (brush); + } + if (b[1]) + { + FreeBrush (b[1]); + *back = CopyBrush (brush); + } + return; + } + + // add the midwinding to both sides + for (i=0 ; i<2 ; i++) + { + cs = &b[i]->sides[b[i]->numsides]; + b[i]->numsides++; + + cs->planenum = planenum^i^1; + cs->texinfo = TEXINFO_NODE; + cs->visible = false; + cs->tested = false; + if (i==0) + cs->winding = CopyWinding (midwinding); + else + cs->winding = midwinding; + } + +{ + vec_t v1; + int i; + + for (i=0 ; i<2 ; i++) + { + v1 = BrushVolume (b[i]); + if (v1 < 1.0) + { + FreeBrush (b[i]); + b[i] = NULL; +// qprintf ("tiny volume after clip\n"); + } + } +} + + *front = b[0]; + *back = b[1]; +} + +/* +================ +SplitBrushList +================ +*/ +void SplitBrushList (bspbrush_t *brushes, + node_t *node, bspbrush_t **front, bspbrush_t **back) +{ + bspbrush_t *brush, *newbrush, *newbrush2; + side_t *side; + int sides; + int i; + + *front = *back = NULL; + + for (brush = brushes ; brush ; brush=brush->next) + { + sides = brush->side; + + if (sides == PSIDE_BOTH) + { // split into two brushes + SplitBrush (brush, node->planenum, &newbrush, &newbrush2); + if (newbrush) + { + newbrush->next = *front; + *front = newbrush; + } + if (newbrush2) + { + newbrush2->next = *back; + *back = newbrush2; + } + continue; + } + + newbrush = CopyBrush (brush); + + // if the planenum is actualy a part of the brush + // find the plane and flag it as used so it won't be tried + // as a splitter again + if (sides & PSIDE_FACING) + { + for (i=0 ; inumsides ; i++) + { + side = newbrush->sides + i; + if ( (side->planenum& ~1) == node->planenum) + side->texinfo = TEXINFO_NODE; + } + } + + + if (sides & PSIDE_FRONT) + { + newbrush->next = *front; + *front = newbrush; + continue; + } + if (sides & PSIDE_BACK) + { + newbrush->next = *back; + *back = newbrush; + continue; + } + } +} + + +/* +================ +BuildTree_r +================ +*/ +node_t *BuildTree_r (node_t *node, bspbrush_t *brushes) +{ + node_t *newnode; + side_t *bestside; + int i; + bspbrush_t *children[2]; + + if (numthreads == 1) + c_nodes++; + + if (drawflag) + DrawBrushList (brushes, node); + + // find the best plane to use as a splitter + bestside = SelectSplitSide (brushes, node); + if (!bestside) + { + // leaf node + node->side = NULL; + node->planenum = -1; + LeafNode (node, brushes); + return node; + } + + // this is a splitplane node + node->side = bestside; + node->planenum = bestside->planenum & ~1; // always use front facing + + SplitBrushList (brushes, node, &children[0], &children[1]); + FreeBrushList (brushes); + + // allocate children before recursing + for (i=0 ; i<2 ; i++) + { + newnode = AllocNode (); + newnode->parent = node; + node->children[i] = newnode; + } + + SplitBrush (node->volume, node->planenum, &node->children[0]->volume, + &node->children[1]->volume); + + // recursively process children + for (i=0 ; i<2 ; i++) + { + node->children[i] = BuildTree_r (node->children[i], children[i]); + } + + return node; +} + +//=========================================================== + +/* +================= +BrushBSP + +The incoming list will be freed before exiting +================= +*/ +tree_t *BrushBSP (bspbrush_t *brushlist, vec3_t mins, vec3_t maxs) +{ + node_t *node; + bspbrush_t *b; + int c_faces, c_nonvisfaces; + int c_brushes; + tree_t *tree; + int i; + vec_t volume; + + qprintf ("--- BrushBSP ---\n"); + + tree = AllocTree (); + + c_faces = 0; + c_nonvisfaces = 0; + c_brushes = 0; + for (b=brushlist ; b ; b=b->next) + { + c_brushes++; + + volume = BrushVolume (b); + if (volume < microvolume) + { + printf ("WARNING: entity %i, brush %i: microbrush\n", + b->original->entitynum, b->original->brushnum); + } + + for (i=0 ; inumsides ; i++) + { + if (b->sides[i].bevel) + continue; + if (!b->sides[i].winding) + continue; + if (b->sides[i].texinfo == TEXINFO_NODE) + continue; + if (b->sides[i].visible) + c_faces++; + else + c_nonvisfaces++; + } + + AddPointToBounds (b->mins, tree->mins, tree->maxs); + AddPointToBounds (b->maxs, tree->mins, tree->maxs); + } + + qprintf ("%5i brushes\n", c_brushes); + qprintf ("%5i visible faces\n", c_faces); + qprintf ("%5i nonvisible faces\n", c_nonvisfaces); + + c_nodes = 0; + c_nonvis = 0; + node = AllocNode (); + + node->volume = BrushFromBounds (mins, maxs); + + tree->headnode = node; + + node = BuildTree_r (node, brushlist); + qprintf ("%5i visible nodes\n", c_nodes/2 - c_nonvis); + qprintf ("%5i nonvis nodes\n", c_nonvis); + qprintf ("%5i leafs\n", (c_nodes+1)/2); +#if 0 +{ // debug code +static node_t *tnode; +vec3_t p; + +p[0] = -1469; +p[1] = -118; +p[2] = 119; +tnode = PointInLeaf (tree->headnode, p); +printf ("contents: %i\n", tnode->contents); +p[0] = 0; +} +#endif + return tree; +} + diff --git a/tools/quake2/extra/bsp/qbsp3/csg.c b/tools/quake2/extra/bsp/qbsp3/csg.c new file mode 100644 index 00000000..2d69aa22 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/csg.c @@ -0,0 +1,635 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +/* + +tag all brushes with original contents +brushes may contain multiple contents +there will be no brush overlap after csg phase + + + + +each side has a count of the other sides it splits + +the best split will be the one that minimizes the total split counts +of all remaining sides + +precalc side on plane table + +evaluate split side +{ +cost = 0 +for all sides + for all sides + get + if side splits side and splitside is on same child + cost++; +} + + + */ + +void SplitBrush2 (bspbrush_t *brush, int planenum, + bspbrush_t **front, bspbrush_t **back) +{ + SplitBrush (brush, planenum, front, back); +#if 0 + if (*front && (*front)->sides[(*front)->numsides-1].texinfo == -1) + (*front)->sides[(*front)->numsides-1].texinfo = (*front)->sides[0].texinfo; // not -1 + if (*back && (*back)->sides[(*back)->numsides-1].texinfo == -1) + (*back)->sides[(*back)->numsides-1].texinfo = (*back)->sides[0].texinfo; // not -1 +#endif +} + +/* +=============== +SubtractBrush + +Returns a list of brushes that remain after B is subtracted from A. +May by empty if A is contained inside B. + +The originals are undisturbed. +=============== +*/ +bspbrush_t *SubtractBrush (bspbrush_t *a, bspbrush_t *b) +{ // a - b = out (list) + int i; + bspbrush_t *front, *back; + bspbrush_t *out, *in; + + in = a; + out = NULL; + for (i=0 ; inumsides && in ; i++) + { + SplitBrush2 (in, b->sides[i].planenum, &front, &back); + if (in != a) + FreeBrush (in); + if (front) + { // add to list + front->next = out; + out = front; + } + in = back; + } + if (in) + FreeBrush (in); + else + { // didn't really intersect + FreeBrushList (out); + return a; + } + return out; +} + +/* +=============== +IntersectBrush + +Returns a single brush made up by the intersection of the +two provided brushes, or NULL if they are disjoint. + +The originals are undisturbed. +=============== +*/ +bspbrush_t *IntersectBrush (bspbrush_t *a, bspbrush_t *b) +{ + int i; + bspbrush_t *front, *back; + bspbrush_t *in; + + in = a; + for (i=0 ; inumsides && in ; i++) + { + SplitBrush2 (in, b->sides[i].planenum, &front, &back); + if (in != a) + FreeBrush (in); + if (front) + FreeBrush (front); + in = back; + } + + if (in == a) + return NULL; + + in->next = NULL; + return in; +} + + +/* +=============== +BrushesDisjoint + +Returns true if the two brushes definately do not intersect. +There will be false negatives for some non-axial combinations. +=============== +*/ +qboolean BrushesDisjoint (bspbrush_t *a, bspbrush_t *b) +{ + int i, j; + + // check bounding boxes + for (i=0 ; i<3 ; i++) + if (a->mins[i] >= b->maxs[i] + || a->maxs[i] <= b->mins[i]) + return true; // bounding boxes don't overlap + + // check for opposing planes + for (i=0 ; inumsides ; i++) + { + for (j=0 ; jnumsides ; j++) + { + if (a->sides[i].planenum == + (b->sides[j].planenum^1) ) + return true; // opposite planes, so not touching + } + } + + return false; // might intersect +} + +/* +=============== +IntersectionContents + +Returns a content word for the intersection of two brushes. +Some combinations will generate a combination (water + clip), +but most will be the stronger of the two contents. +=============== +*/ +int IntersectionContents (int c1, int c2) +{ + int out; + + out = c1 | c2; + + if (out & CONTENTS_SOLID) + out = CONTENTS_SOLID; + + return out; +} + + +int minplanenums[3]; +int maxplanenums[3]; + +/* +=============== +ClipBrushToBox + +Any planes shared with the box edge will be set to no texinfo +=============== +*/ +bspbrush_t *ClipBrushToBox (bspbrush_t *brush, vec3_t clipmins, vec3_t clipmaxs) +{ + int i, j; + bspbrush_t *front, *back; + int p; + + for (j=0 ; j<2 ; j++) + { + if (brush->maxs[j] > clipmaxs[j]) + { + SplitBrush (brush, maxplanenums[j], &front, &back); + if (front) + FreeBrush (front); + brush = back; + if (!brush) + return NULL; + } + if (brush->mins[j] < clipmins[j]) + { + SplitBrush (brush, minplanenums[j], &front, &back); + if (back) + FreeBrush (back); + brush = front; + if (!brush) + return NULL; + } + } + + // remove any colinear faces + + for (i=0 ; inumsides ; i++) + { + p = brush->sides[i].planenum & ~1; + if (p == maxplanenums[0] || p == maxplanenums[1] + || p == minplanenums[0] || p == minplanenums[1]) + { + brush->sides[i].texinfo = TEXINFO_NODE; + brush->sides[i].visible = false; + } + } + return brush; +} + +/* +=============== +MakeBspBrushList +=============== +*/ +bspbrush_t *MakeBspBrushList (int startbrush, int endbrush, + vec3_t clipmins, vec3_t clipmaxs) +{ + mapbrush_t *mb; + bspbrush_t *brushlist, *newbrush; + int i, j; + int c_faces; + int c_brushes; + int numsides; + int vis; + vec3_t normal; + float dist; + + for (i=0 ; i<2 ; i++) + { + VectorClear (normal); + normal[i] = 1; + dist = clipmaxs[i]; + maxplanenums[i] = FindFloatPlane (normal, dist); + dist = clipmins[i]; + minplanenums[i] = FindFloatPlane (normal, dist); + } + + brushlist = NULL; + c_faces = 0; + c_brushes = 0; + + for (i=startbrush ; inumsides; + if (!numsides) + continue; + // make sure the brush has at least one face showing + vis = 0; + for (j=0 ; joriginal_sides[j].visible && mb->original_sides[j].winding) + vis++; +#if 0 + if (!vis) + continue; // no faces at all +#endif + // if the brush is outside the clip area, skip it + for (j=0 ; j<3 ; j++) + if (mb->mins[j] >= clipmaxs[j] + || mb->maxs[j] <= clipmins[j]) + break; + if (j != 3) + continue; + + // + // make a copy of the brush + // + newbrush = AllocBrush (mb->numsides); + newbrush->original = mb; + newbrush->numsides = mb->numsides; + memcpy (newbrush->sides, mb->original_sides, numsides*sizeof(side_t)); + for (j=0 ; jsides[j].winding) + newbrush->sides[j].winding = CopyWinding (newbrush->sides[j].winding); + if (newbrush->sides[j].surf & SURF_HINT) + newbrush->sides[j].visible = true; // hints are always visible + } + VectorCopy (mb->mins, newbrush->mins); + VectorCopy (mb->maxs, newbrush->maxs); + + // + // carve off anything outside the clip box + // + newbrush = ClipBrushToBox (newbrush, clipmins, clipmaxs); + if (!newbrush) + continue; + + c_faces += vis; + c_brushes++; + + newbrush->next = brushlist; + brushlist = newbrush; + } + + return brushlist; +} + +/* +=============== +AddBspBrushListToTail +=============== +*/ +bspbrush_t *AddBrushListToTail (bspbrush_t *list, bspbrush_t *tail) +{ + bspbrush_t *walk, *next; + + for (walk=list ; walk ; walk=next) + { // add to end of list + next = walk->next; + walk->next = NULL; + tail->next = walk; + tail = walk; + } + + return tail; +} + +/* +=========== +CullList + +Builds a new list that doesn't hold the given brush +=========== +*/ +bspbrush_t *CullList (bspbrush_t *list, bspbrush_t *skip1) +{ + bspbrush_t *newlist; + bspbrush_t *next; + + newlist = NULL; + + for ( ; list ; list = next) + { + next = list->next; + if (list == skip1) + { + FreeBrush (list); + continue; + } + list->next = newlist; + newlist = list; + } + return newlist; +} + + +/* +================== +WriteBrushMap +================== +*/ +void WriteBrushMap (char *name, bspbrush_t *list) +{ + FILE *f; + side_t *s; + int i; + winding_t *w; + + printf ("writing %s\n", name); + f = fopen (name, "wb"); + if (!f) + Error ("Can't write %s\b", name); + + fprintf (f, "{\n\"classname\" \"worldspawn\"\n"); + + for ( ; list ; list=list->next ) + { + fprintf (f, "{\n"); + for (i=0,s=list->sides ; inumsides ; i++,s++) + { + w = BaseWindingForPlane (mapplanes[s->planenum].normal, mapplanes[s->planenum].dist); + + fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]); + fprintf (f,"( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]); + fprintf (f,"( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]); + + fprintf (f, "%s 0 0 0 1 1\n", texinfo[s->texinfo].texture); + FreeWinding (w); + } + fprintf (f, "}\n"); + } + fprintf (f, "}\n"); + + fclose (f); + +} + +/* +================== +BrushGE + +Returns true if b1 is allowed to bite b2 +================== +*/ +qboolean BrushGE (bspbrush_t *b1, bspbrush_t *b2) +{ + // detail brushes never bite structural brushes + if ( (b1->original->contents & CONTENTS_DETAIL) + && !(b2->original->contents & CONTENTS_DETAIL) ) + return false; + if (b1->original->contents & CONTENTS_SOLID) + return true; + return false; +} + +/* +================= +ChopBrushes + +Carves any intersecting solid brushes into the minimum number +of non-intersecting brushes. +================= +*/ +bspbrush_t *ChopBrushes (bspbrush_t *head) +{ + bspbrush_t *b1, *b2, *next; + bspbrush_t *tail; + bspbrush_t *keep; + bspbrush_t *sub, *sub2; + int c1, c2; + + qprintf ("---- ChopBrushes ----\n"); + qprintf ("original brushes: %i\n", CountBrushList (head)); + +#if 0 + if (startbrush == 0) + WriteBrushList ("before.gl", head, false); +#endif + keep = NULL; + +newlist: + // find tail + if (!head) + return NULL; + for (tail=head ; tail->next ; tail=tail->next) + ; + + for (b1=head ; b1 ; b1=next) + { + next = b1->next; + for (b2=b1->next ; b2 ; b2 = b2->next) + { + if (BrushesDisjoint (b1, b2)) + continue; + + sub = NULL; + sub2 = NULL; + c1 = 999999; + c2 = 999999; + + if ( BrushGE (b2, b1) ) + { + sub = SubtractBrush (b1, b2); + if (sub == b1) + continue; // didn't really intersect + if (!sub) + { // b1 is swallowed by b2 + head = CullList (b1, b1); + goto newlist; + } + c1 = CountBrushList (sub); + } + + if ( BrushGE (b1, b2) ) + { + sub2 = SubtractBrush (b2, b1); + if (sub2 == b2) + continue; // didn't really intersect + if (!sub2) + { // b2 is swallowed by b1 + FreeBrushList (sub); + head = CullList (b1, b2); + goto newlist; + } + c2 = CountBrushList (sub2); + } + + if (!sub && !sub2) + continue; // neither one can bite + + // only accept if it didn't fragment + // (commening this out allows full fragmentation) + if (c1 > 1 && c2 > 1) + { + if (sub2) + FreeBrushList (sub2); + if (sub) + FreeBrushList (sub); + continue; + } + + if (c1 < c2) + { + if (sub2) + FreeBrushList (sub2); + tail = AddBrushListToTail (sub, tail); + head = CullList (b1, b1); + goto newlist; + } + else + { + if (sub) + FreeBrushList (sub); + tail = AddBrushListToTail (sub2, tail); + head = CullList (b1, b2); + goto newlist; + } + } + + if (!b2) + { // b1 is no longer intersecting anything, so keep it + b1->next = keep; + keep = b1; + } + } + + qprintf ("output brushes: %i\n", CountBrushList (keep)); +#if 0 + { + WriteBrushList ("after.gl", keep, false); + WriteBrushMap ("after.map", keep); + } +#endif + return keep; +} + + +/* +================= +InitialBrushList +================= +*/ +bspbrush_t *InitialBrushList (bspbrush_t *list) +{ + bspbrush_t *b; + bspbrush_t *out, *newb; + int i; + + // only return brushes that have visible faces + out = NULL; + for (b=list ; b ; b=b->next) + { +#if 0 + for (i=0 ; inumsides ; i++) + if (b->sides[i].visible) + break; + if (i == b->numsides) + continue; +#endif + newb = CopyBrush (b); + newb->next = out; + out = newb; + + // clear visible, so it must be set by MarkVisibleFaces_r + // to be used in the optimized list + for (i=0 ; inumsides ; i++) + { + newb->sides[i].original = &b->sides[i]; +// newb->sides[i].visible = true; + b->sides[i].visible = false; + } + } + + return out; +} + +/* +================= +OptimizedBrushList +================= +*/ +bspbrush_t *OptimizedBrushList (bspbrush_t *list) +{ + bspbrush_t *b; + bspbrush_t *out, *newb; + int i; + + // only return brushes that have visible faces + out = NULL; + for (b=list ; b ; b=b->next) + { + for (i=0 ; inumsides ; i++) + if (b->sides[i].visible) + break; + if (i == b->numsides) + continue; + newb = CopyBrush (b); + newb->next = out; + out = newb; + } + +// WriteBrushList ("vis.gl", out, true); + + return out; +} diff --git a/tools/quake2/extra/bsp/qbsp3/faces.c b/tools/quake2/extra/bsp/qbsp3/faces.c new file mode 100644 index 00000000..1bbc922b --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/faces.c @@ -0,0 +1,1076 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +/* + + some faces will be removed before saving, but still form nodes: + + the insides of sky volumes + meeting planes of different water current volumes + +*/ + +// undefine for dumb linear searches +#define USE_HASHING + +#define INTEGRAL_EPSILON 0.01 +#define POINT_EPSILON 0.5 +#define OFF_EPSILON 0.5 + +int c_merge; +int c_subdivide; + +int c_totalverts; +int c_uniqueverts; +int c_degenerate; +int c_tjunctions; +int c_faceoverflows; +int c_facecollapse; +int c_badstartverts; + +#define MAX_SUPERVERTS 512 +int superverts[MAX_SUPERVERTS]; +int numsuperverts; + +face_t *edgefaces[MAX_MAP_EDGES][2]; +int firstmodeledge = 1; +int firstmodelface; + +int c_tryedges; + +vec3_t edge_dir; +vec3_t edge_start; +vec_t edge_len; + +int num_edge_verts; +int edge_verts[MAX_MAP_VERTS]; + + +float subdivide_size = 240; + + +face_t *NewFaceFromFace (face_t *f); + +//=========================================================================== + +typedef struct hashvert_s +{ + struct hashvert_s *next; + int num; +} hashvert_t; + + +#define HASH_SIZE 64 + + +int vertexchain[MAX_MAP_VERTS]; // the next vertex in a hash chain +int hashverts[HASH_SIZE*HASH_SIZE]; // a vertex number, or 0 for no verts + +face_t *edgefaces[MAX_MAP_EDGES][2]; + +//============================================================================ + + +unsigned HashVec (vec3_t vec) +{ + int x, y; + + x = (4096 + (int)(vec[0]+0.5)) >> 7; + y = (4096 + (int)(vec[1]+0.5)) >> 7; + + if ( x < 0 || x >= HASH_SIZE || y < 0 || y >= HASH_SIZE ) + Error ("HashVec: point outside valid range"); + + return y*HASH_SIZE + x; +} + +#ifdef USE_HASHING +/* +============= +GetVertex + +Uses hashing +============= +*/ +int GetVertexnum (vec3_t in) +{ + int h; + int i; + float *p; + vec3_t vert; + int vnum; + + c_totalverts++; + + for (i=0 ; i<3 ; i++) + { + if ( fabs(in[i] - Q_rint(in[i])) < INTEGRAL_EPSILON) + vert[i] = Q_rint(in[i]); + else + vert[i] = in[i]; + } + + h = HashVec (vert); + + for (vnum=hashverts[h] ; vnum ; vnum=vertexchain[vnum]) + { + p = dvertexes[vnum].point; + if ( fabs(p[0]-vert[0]) 4096) + Error ("GetVertexnum: outside +/- 4096"); + } + + // search for an existing vertex match + for (i=0, dv=dvertexes ; ipoint[j]; + if ( d > POINT_EPSILON || d < -POINT_EPSILON) + break; + } + if (j == 3) + return i; // a match + } + + // new point + if (numvertexes == MAX_MAP_VERTS) + Error ("MAX_MAP_VERTS"); + VectorCopy (v, dv->point); + numvertexes++; + c_uniqueverts++; + + return numvertexes-1; +} +#endif + + +/* +================== +FaceFromSuperverts + +The faces vertexes have beeb added to the superverts[] array, +and there may be more there than can be held in a face (MAXEDGES). + +If less, the faces vertexnums[] will be filled in, otherwise +face will reference a tree of split[] faces until all of the +vertexnums can be added. + +superverts[base] will become face->vertexnums[0], and the others +will be circularly filled in. +================== +*/ +void FaceFromSuperverts (node_t *node, face_t *f, int base) +{ + face_t *newf; + int remaining; + int i; + + remaining = numsuperverts; + while (remaining > MAXEDGES) + { // must split into two faces, because of vertex overload + c_faceoverflows++; + + newf = f->split[0] = NewFaceFromFace (f); + newf = f->split[0]; + newf->next = node->faces; + node->faces = newf; + + newf->numpoints = MAXEDGES; + for (i=0 ; ivertexnums[i] = superverts[(i+base)%numsuperverts]; + + f->split[1] = NewFaceFromFace (f); + f = f->split[1]; + f->next = node->faces; + node->faces = f; + + remaining -= (MAXEDGES-2); + base = (base+MAXEDGES-1)%numsuperverts; + } + + // copy the vertexes back to the face + f->numpoints = remaining; + for (i=0 ; ivertexnums[i] = superverts[(i+base)%numsuperverts]; +} + + +/* +================== +EmitFaceVertexes +================== +*/ +void EmitFaceVertexes (node_t *node, face_t *f) +{ + winding_t *w; + int i; + + if (f->merged || f->split[0] || f->split[1]) + return; + + w = f->w; + for (i=0 ; inumpoints ; i++) + { + if (noweld) + { // make every point unique + if (numvertexes == MAX_MAP_VERTS) + Error ("MAX_MAP_VERTS"); + superverts[i] = numvertexes; + VectorCopy (w->p[i], dvertexes[numvertexes].point); + numvertexes++; + c_uniqueverts++; + c_totalverts++; + } + else + superverts[i] = GetVertexnum (w->p[i]); + } + numsuperverts = w->numpoints; + + // this may fragment the face if > MAXEDGES + FaceFromSuperverts (node, f, 0); +} + +/* +================== +EmitVertexes_r +================== +*/ +void EmitVertexes_r (node_t *node) +{ + int i; + face_t *f; + + if (node->planenum == PLANENUM_LEAF) + return; + + for (f=node->faces ; f ; f=f->next) + { + EmitFaceVertexes (node, f); + } + + for (i=0 ; i<2 ; i++) + EmitVertexes_r (node->children[i]); +} + + +#ifdef USE_HASHING +/* +========== +FindEdgeVerts + +Uses the hash tables to cut down to a small number +========== +*/ +void FindEdgeVerts (vec3_t v1, vec3_t v2) +{ + int x1, x2, y1, y2, t; + int x, y; + int vnum; + +#if 0 +{ + int i; + num_edge_verts = numvertexes-1; + for (i=0 ; i> 7; + y1 = (4096 + (int)(v1[1]+0.5)) >> 7; + x2 = (4096 + (int)(v2[0]+0.5)) >> 7; + y2 = (4096 + (int)(v2[1]+0.5)) >> 7; + + if (x1 > x2) + { + t = x1; + x1 = x2; + x2 = t; + } + if (y1 > y2) + { + t = y1; + y1 = y2; + y2 = t; + } +#if 0 + x1--; + x2++; + y1--; + y2++; + if (x1 < 0) + x1 = 0; + if (x2 >= HASH_SIZE) + x2 = HASH_SIZE; + if (y1 < 0) + y1 = 0; + if (y2 >= HASH_SIZE) + y2 = HASH_SIZE; +#endif + num_edge_verts = 0; + for (x=x1 ; x <= x2 ; x++) + { + for (y=y1 ; y <= y2 ; y++) + { + for (vnum=hashverts[y*HASH_SIZE+x] ; vnum ; vnum=vertexchain[vnum]) + { + edge_verts[num_edge_verts++] = vnum; + } + } + } +} + +#else +/* +========== +FindEdgeVerts + +Forced a dumb check of everything +========== +*/ +void FindEdgeVerts (vec3_t v1, vec3_t v2) +{ + int i; + + num_edge_verts = numvertexes-1; + for (i=0 ; i= end) + continue; // off an end + VectorMA (edge_start, dist, edge_dir, exact); + VectorSubtract (p, exact, off); + error = VectorLength (off); + + if (fabs(error) > OFF_EPSILON) + continue; // not on the edge + + // break the edge + c_tjunctions++; + TestEdge (start, dist, p1, j, k+1); + TestEdge (dist, end, j, p2, k+1); + return; + } + + // the edge p1 to p2 is now free of tjunctions + if (numsuperverts >= MAX_SUPERVERTS) + Error ("MAX_SUPERVERTS"); + superverts[numsuperverts] = p1; + numsuperverts++; +} + +/* +================== +FixFaceEdges + +================== +*/ +void FixFaceEdges (node_t *node, face_t *f) +{ + int p1, p2; + int i; + vec3_t e2; + vec_t len; + int count[MAX_SUPERVERTS], start[MAX_SUPERVERTS]; + int base; + + if (f->merged || f->split[0] || f->split[1]) + return; + + numsuperverts = 0; + + for (i=0 ; inumpoints ; i++) + { + p1 = f->vertexnums[i]; + p2 = f->vertexnums[(i+1)%f->numpoints]; + + VectorCopy (dvertexes[p1].point, edge_start); + VectorCopy (dvertexes[p2].point, e2); + + FindEdgeVerts (edge_start, e2); + + VectorSubtract (e2, edge_start, edge_dir); + len = VectorNormalize (edge_dir, edge_dir); + + start[i] = numsuperverts; + TestEdge (0, len, p1, p2, 0); + + count[i] = numsuperverts - start[i]; + } + + if (numsuperverts < 3) + { // entire face collapsed + f->numpoints = 0; + c_facecollapse++; + return; + } + + // we want to pick a vertex that doesn't have tjunctions + // on either side, which can cause artifacts on trifans, + // especially underwater + for (i=0 ; inumpoints ; i++) + { + if (count[i] == 1 && count[(i+f->numpoints-1)%f->numpoints] == 1) + break; + } + if (i == f->numpoints) + { + f->badstartvert = true; + c_badstartverts++; + base = 0; + } + else + { // rotate the vertex order + base = start[i]; + } + + // this may fragment the face if > MAXEDGES + FaceFromSuperverts (node, f, base); +} + +/* +================== +FixEdges_r +================== +*/ +void FixEdges_r (node_t *node) +{ + int i; + face_t *f; + + if (node->planenum == PLANENUM_LEAF) + return; + + for (f=node->faces ; f ; f=f->next) + FixFaceEdges (node, f); + + for (i=0 ; i<2 ; i++) + FixEdges_r (node->children[i]); +} + +/* +=========== +FixTjuncs + +=========== +*/ +void FixTjuncs (node_t *headnode) +{ + // snap and merge all vertexes + qprintf ("---- snap verts ----\n"); + memset (hashverts, 0, sizeof(hashverts)); + c_totalverts = 0; + c_uniqueverts = 0; + c_faceoverflows = 0; + EmitVertexes_r (headnode); + qprintf ("%i unique from %i\n", c_uniqueverts, c_totalverts); + + // break edges on tjunctions + qprintf ("---- tjunc ----\n"); + c_tryedges = 0; + c_degenerate = 0; + c_facecollapse = 0; + c_tjunctions = 0; + if (!notjunc) + FixEdges_r (headnode); + qprintf ("%5i edges degenerated\n", c_degenerate); + qprintf ("%5i faces degenerated\n", c_facecollapse); + qprintf ("%5i edges added by tjunctions\n", c_tjunctions); + qprintf ("%5i faces added by tjunctions\n", c_faceoverflows); + qprintf ("%5i bad start verts\n", c_badstartverts); +} + + +//======================================================== + +int c_faces; + +face_t *AllocFace (void) +{ + face_t *f; + + f = malloc(sizeof(*f)); + memset (f, 0, sizeof(*f)); + c_faces++; + + return f; +} + +face_t *NewFaceFromFace (face_t *f) +{ + face_t *newf; + + newf = AllocFace (); + *newf = *f; + newf->merged = NULL; + newf->split[0] = newf->split[1] = NULL; + newf->w = NULL; + return newf; +} + +void FreeFace (face_t *f) +{ + if (f->w) + FreeWinding (f->w); + free (f); + c_faces--; +} + +//======================================================== + +/* +================== +GetEdge + +Called by writebsp. +Don't allow four way edges +================== +*/ +int GetEdge2 (int v1, int v2, face_t *f) +{ + dedge_t *edge; + int i; + + c_tryedges++; + + if (!noshare) + { + for (i=firstmodeledge ; i < numedges ; i++) + { + edge = &dedges[i]; + if (v1 == edge->v[1] && v2 == edge->v[0] + && edgefaces[i][0]->contents == f->contents) + { + if (edgefaces[i][1]) + // printf ("WARNING: multiple backward edge\n"); + continue; + edgefaces[i][1] = f; + return -i; + } + #if 0 + if (v1 == edge->v[0] && v2 == edge->v[1]) + { + printf ("WARNING: multiple forward edge\n"); + return i; + } + #endif + } + } + +// emit an edge + if (numedges >= MAX_MAP_EDGES) + Error ("numedges == MAX_MAP_EDGES"); + edge = &dedges[numedges]; + numedges++; + edge->v[0] = v1; + edge->v[1] = v2; + edgefaces[numedges-1][0] = f; + + return numedges-1; +} + +/* +=========================================================================== + +FACE MERGING + +=========================================================================== +*/ + +#define CONTINUOUS_EPSILON 0.001 + +/* +============= +TryMergeWinding + +If two polygons share a common edge and the edges that meet at the +common points are both inside the other polygons, merge them + +Returns NULL if the faces couldn't be merged, or the new face. +The originals will NOT be freed. +============= +*/ +winding_t *TryMergeWinding (winding_t *f1, winding_t *f2, vec3_t planenormal) +{ + vec_t *p1, *p2, *p3, *p4, *back; + winding_t *newf; + int i, j, k, l; + vec3_t normal, delta; + vec_t dot; + qboolean keep1, keep2; + + + // + // find a common edge + // + p1 = p2 = NULL; // stop compiler warning + j = 0; // + + for (i=0 ; inumpoints ; i++) + { + p1 = f1->p[i]; + p2 = f1->p[(i+1)%f1->numpoints]; + for (j=0 ; jnumpoints ; j++) + { + p3 = f2->p[j]; + p4 = f2->p[(j+1)%f2->numpoints]; + for (k=0 ; k<3 ; k++) + { + if (fabs(p1[k] - p4[k]) > EQUAL_EPSILON) + break; + if (fabs(p2[k] - p3[k]) > EQUAL_EPSILON) + break; + } + if (k==3) + break; + } + if (j < f2->numpoints) + break; + } + + if (i == f1->numpoints) + return NULL; // no matching edges + + // + // check slope of connected lines + // if the slopes are colinear, the point can be removed + // + back = f1->p[(i+f1->numpoints-1)%f1->numpoints]; + VectorSubtract (p1, back, delta); + CrossProduct (planenormal, delta, normal); + VectorNormalize (normal, normal); + + back = f2->p[(j+2)%f2->numpoints]; + VectorSubtract (back, p1, delta); + dot = DotProduct (delta, normal); + if (dot > CONTINUOUS_EPSILON) + return NULL; // not a convex polygon + keep1 = (qboolean)(dot < -CONTINUOUS_EPSILON); + + back = f1->p[(i+2)%f1->numpoints]; + VectorSubtract (back, p2, delta); + CrossProduct (planenormal, delta, normal); + VectorNormalize (normal, normal); + + back = f2->p[(j+f2->numpoints-1)%f2->numpoints]; + VectorSubtract (back, p2, delta); + dot = DotProduct (delta, normal); + if (dot > CONTINUOUS_EPSILON) + return NULL; // not a convex polygon + keep2 = (qboolean)(dot < -CONTINUOUS_EPSILON); + + // + // build the new polygon + // + newf = AllocWinding (f1->numpoints + f2->numpoints); + + // copy first polygon + for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints) + { + if (k==(i+1)%f1->numpoints && !keep2) + continue; + + VectorCopy (f1->p[k], newf->p[newf->numpoints]); + newf->numpoints++; + } + + // copy second polygon + for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints) + { + if (l==(j+1)%f2->numpoints && !keep1) + continue; + VectorCopy (f2->p[l], newf->p[newf->numpoints]); + newf->numpoints++; + } + + return newf; +} + +/* +============= +TryMerge + +If two polygons share a common edge and the edges that meet at the +common points are both inside the other polygons, merge them + +Returns NULL if the faces couldn't be merged, or the new face. +The originals will NOT be freed. +============= +*/ +face_t *TryMerge (face_t *f1, face_t *f2, vec3_t planenormal) +{ + face_t *newf; + winding_t *nw; + + if (!f1->w || !f2->w) + return NULL; + if (f1->texinfo != f2->texinfo) + return NULL; + if (f1->planenum != f2->planenum) // on front and back sides + return NULL; + if (f1->contents != f2->contents) + return NULL; + + + nw = TryMergeWinding (f1->w, f2->w, planenormal); + if (!nw) + return NULL; + + c_merge++; + newf = NewFaceFromFace (f1); + newf->w = nw; + + f1->merged = newf; + f2->merged = newf; + + return newf; +} + +/* +=============== +MergeNodeFaces +=============== +*/ +void MergeNodeFaces (node_t *node) +{ + face_t *f1, *f2, *end; + face_t *merged; + plane_t *plane; + + plane = &mapplanes[node->planenum]; + merged = NULL; + + for (f1 = node->faces ; f1 ; f1 = f1->next) + { + if (f1->merged || f1->split[0] || f1->split[1]) + continue; + for (f2 = node->faces ; f2 != f1 ; f2=f2->next) + { + if (f2->merged || f2->split[0] || f2->split[1]) + continue; + merged = TryMerge (f1, f2, plane->normal); + if (!merged) + continue; + + // add merged to the end of the node face list + // so it will be checked against all the faces again + for (end = node->faces ; end->next ; end = end->next) + ; + merged->next = NULL; + end->next = merged; + break; + } + } +} + +//===================================================================== + +/* +=============== +SubdivideFace + +Chop up faces that are larger than we want in the surface cache +=============== +*/ +void SubdivideFace (node_t *node, face_t *f) +{ + float mins, maxs; + vec_t v; + int axis, i; + texinfo_t *tex; + vec3_t temp; + vec_t dist; + winding_t *w, *frontw, *backw; + + if (f->merged) + return; + +// special (non-surface cached) faces don't need subdivision + tex = &texinfo[f->texinfo]; + + if ( tex->flags & (SURF_WARP|SURF_SKY) ) + { + return; + } + + for (axis = 0 ; axis < 2 ; axis++) + { + while (1) + { + mins = 999999; + maxs = -999999; + + VectorCopy (tex->vecs[axis], temp); + w = f->w; + for (i=0 ; inumpoints ; i++) + { + v = DotProduct (w->p[i], temp); + if (v < mins) + mins = v; + if (v > maxs) + maxs = v; + } +#if 0 + if (maxs - mins <= 0) + Error ("zero extents"); +#endif + if (axis == 2) + { // allow double high walls + if (maxs - mins <= subdivide_size/* *2 */) + break; + } + else if (maxs - mins <= subdivide_size) + break; + + // split it + c_subdivide++; + + v = VectorNormalize (temp, temp); + + dist = (mins + subdivide_size - 16)/v; + + ClipWindingEpsilon (w, temp, dist, ON_EPSILON, &frontw, &backw); + if (!frontw || !backw) + Error ("SubdivideFace: didn't split the polygon"); + + f->split[0] = NewFaceFromFace (f); + f->split[0]->w = frontw; + f->split[0]->next = node->faces; + node->faces = f->split[0]; + + f->split[1] = NewFaceFromFace (f); + f->split[1]->w = backw; + f->split[1]->next = node->faces; + node->faces = f->split[1]; + + SubdivideFace (node, f->split[0]); + SubdivideFace (node, f->split[1]); + return; + } + } +} + +void SubdivideNodeFaces (node_t *node) +{ + face_t *f; + + for (f = node->faces ; f ; f=f->next) + { + SubdivideFace (node, f); + } +} + +//=========================================================================== + +int c_nodefaces; + + +/* +============ +FaceFromPortal + +============ +*/ +face_t *FaceFromPortal (portal_t *p, int pside) +{ + face_t *f; + side_t *side; + + side = p->side; + if (!side) + return NULL; // portal does not bridge different visible contents + + f = AllocFace (); + + f->texinfo = side->texinfo; + f->planenum = (side->planenum & ~1) | pside; + f->portal = p; + + if ( (p->nodes[pside]->contents & CONTENTS_WINDOW) + && VisibleContents(p->nodes[!pside]->contents^p->nodes[pside]->contents) == CONTENTS_WINDOW ) + return NULL; // don't show insides of windows + + if (pside) + { + f->w = ReverseWinding(p->winding); + f->contents = p->nodes[1]->contents; + } + else + { + f->w = CopyWinding(p->winding); + f->contents = p->nodes[0]->contents; + } + return f; +} + + +/* +=============== +MakeFaces_r + +If a portal will make a visible face, +mark the side that originally created it + + solid / empty : solid + solid / water : solid + water / empty : water + water / water : none +=============== +*/ +void MakeFaces_r (node_t *node) +{ + portal_t *p; + int s; + + // recurse down to leafs + if (node->planenum != PLANENUM_LEAF) + { + MakeFaces_r (node->children[0]); + MakeFaces_r (node->children[1]); + + // merge together all visible faces on the node + if (!nomerge) + MergeNodeFaces (node); + if (!nosubdiv) + SubdivideNodeFaces (node); + + return; + } + + // solid leafs never have visible faces + if (node->contents & CONTENTS_SOLID) + return; + + // see which portals are valid + for (p=node->portals ; p ; p = p->next[s]) + { + s = (p->nodes[1] == node); + + p->face[s] = FaceFromPortal (p, s); + if (p->face[s]) + { + c_nodefaces++; + p->face[s]->next = p->onnode->faces; + p->onnode->faces = p->face[s]; + } + } +} + +/* +============ +MakeFaces +============ +*/ +void MakeFaces (node_t *node) +{ + qprintf ("--- MakeFaces ---\n"); + c_merge = 0; + c_subdivide = 0; + c_nodefaces = 0; + + MakeFaces_r (node); + + qprintf ("%5i makefaces\n", c_nodefaces); + qprintf ("%5i merged\n", c_merge); + qprintf ("%5i subdivided\n", c_subdivide); +} diff --git a/tools/quake2/extra/bsp/qbsp3/gldraw.c b/tools/quake2/extra/bsp/qbsp3/gldraw.c new file mode 100644 index 00000000..08ab9c45 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/gldraw.c @@ -0,0 +1,232 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include +#include +#include +#include + +#include "qbsp.h" + +// can't use the glvertex3fv functions, because the vec3_t fields +// could be either floats or doubles, depending on DOUBLEVEC_T + +qboolean drawflag; +vec3_t draw_mins, draw_maxs; + + +#define WIN_SIZE 512 + +void InitWindow (void) +{ + auxInitDisplayMode (AUX_SINGLE | AUX_RGB); + auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE); + auxInitWindow ("qcsg"); +} + +void Draw_ClearWindow (void) +{ + static int init; + int w, h, g; + vec_t mx, my; + + if (!drawflag) + return; + + if (!init) + { + init = true; + InitWindow (); + } + + glClearColor (1,0.8,0.8,0); + glClear (GL_COLOR_BUFFER_BIT); + + w = (draw_maxs[0] - draw_mins[0]); + h = (draw_maxs[1] - draw_mins[1]); + + mx = draw_mins[0] + w/2; + my = draw_mins[1] + h/2; + + g = w > h ? w : h; + + glLoadIdentity (); + gluPerspective (90, 1, 2, 16384); + gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0); + + glColor3f (0,0,0); +// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glDisable (GL_DEPTH_TEST); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +#if 0 + glColor4f (1,0,0,0.5); + glBegin (GL_POLYGON); + + glVertex3f (0, 500, 0); + glVertex3f (0, 900, 0); + glVertex3f (0, 900, 100); + glVertex3f (0, 500, 100); + + glEnd (); +#endif + + glFlush (); + +} + +void Draw_SetRed (void) +{ + if (!drawflag) + return; + + glColor3f (1,0,0); +} + +void Draw_SetGrey (void) +{ + if (!drawflag) + return; + + glColor3f (0.5,0.5,0.5); +} + +void Draw_SetBlack (void) +{ + if (!drawflag) + return; + + glColor3f (0,0,0); +} + +void DrawWinding (winding_t *w) +{ + int i; + + if (!drawflag) + return; + + glColor4f (0,0,0,0.5); + glBegin (GL_LINE_LOOP); + for (i=0 ; inumpoints ; i++) + glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] ); + glEnd (); + + glColor4f (0,1,0,0.3); + glBegin (GL_POLYGON); + for (i=0 ; inumpoints ; i++) + glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] ); + glEnd (); + + glFlush (); +} + +void DrawAuxWinding (winding_t *w) +{ + int i; + + if (!drawflag) + return; + + glColor4f (0,0,0,0.5); + glBegin (GL_LINE_LOOP); + for (i=0 ; inumpoints ; i++) + glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] ); + glEnd (); + + glColor4f (1,0,0,0.3); + glBegin (GL_POLYGON); + for (i=0 ; inumpoints ; i++) + glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] ); + glEnd (); + + glFlush (); +} + +//============================================================ + +#define GLSERV_PORT 25001 + +qboolean wins_init; +int draw_socket; + +void GLS_BeginScene (void) +{ + WSADATA winsockdata; + WORD wVersionRequested; + struct sockaddr_in address; + int r; + + if (!wins_init) + { + wins_init = true; + + wVersionRequested = MAKEWORD(1, 1); + + r = WSAStartup (MAKEWORD(1, 1), &winsockdata); + + if (r) + Error ("Winsock initialization failed."); + + } + + // connect a socket to the server + + draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (draw_socket == -1) + Error ("draw_socket failed"); + + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + address.sin_port = GLSERV_PORT; + r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address)); + if (r == -1) + { + closesocket (draw_socket); + draw_socket = 0; + } +} + +void GLS_Winding (winding_t *w, int code) +{ + byte buf[1024]; + int i, j; + + if (!draw_socket) + return; + + ((int *)buf)[0] = w->numpoints; + ((int *)buf)[1] = code; + for (i=0 ; inumpoints ; i++) + for (j=0 ; j<3 ; j++) + ((float *)buf)[2+i*3+j] = w->p[i][j]; + + send (draw_socket, buf, w->numpoints*12+8, 0); +} + +void GLS_EndScene (void) +{ + closesocket (draw_socket); + draw_socket = 0; +} diff --git a/tools/quake2/extra/bsp/qbsp3/glfile.c b/tools/quake2/extra/bsp/qbsp3/glfile.c new file mode 100644 index 00000000..6d767772 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/glfile.c @@ -0,0 +1,149 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +int c_glfaces; + +int PortalVisibleSides (portal_t *p) +{ + int fcon, bcon; + + if (!p->onnode) + return 0; // outside + + fcon = p->nodes[0]->contents; + bcon = p->nodes[1]->contents; + + // same contents never create a face + if (fcon == bcon) + return 0; + + // FIXME: is this correct now? + if (!fcon) + return 1; + if (!bcon) + return 2; + return 0; +} + +void OutputWinding (winding_t *w, FILE *glview) +{ + static int level = 128; + vec_t light; + int i; + + fprintf (glview, "%i\n", w->numpoints); + level+=28; + light = (level&255)/255.0; + for (i=0 ; inumpoints ; i++) + { + fprintf (glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n", + w->p[i][0], + w->p[i][1], + w->p[i][2], + light, + light, + light); + } + fprintf (glview, "\n"); +} + +/* +============= +OutputPortal +============= +*/ +void OutputPortal (portal_t *p, FILE *glview) +{ + winding_t *w; + int sides; + + sides = PortalVisibleSides (p); + if (!sides) + return; + + c_glfaces++; + + w = p->winding; + + if (sides == 2) // back side + w = ReverseWinding (w); + + OutputWinding (w, glview); + + if (sides == 2) + FreeWinding(w); +} + +/* +============= +WriteGLView_r +============= +*/ +void WriteGLView_r (node_t *node, FILE *glview) +{ + portal_t *p, *nextp; + + if (node->planenum != PLANENUM_LEAF) + { + WriteGLView_r (node->children[0], glview); + WriteGLView_r (node->children[1], glview); + return; + } + + // write all the portals + for (p=node->portals ; p ; p=nextp) + { + if (p->nodes[0] == node) + { + OutputPortal (p, glview); + nextp = p->next[0]; + } + else + nextp = p->next[1]; + } +} + +/* +============= +WriteGLView +============= +*/ +void WriteGLView (tree_t *tree, char *source) +{ + char name[1024]; + FILE *glview; + + c_glfaces = 0; + sprintf (name, "%s%s.gl",outbase, source); + printf ("Writing %s\n", name); + + glview = fopen (name, "w"); + if (!glview) + Error ("Couldn't open %s", name); + WriteGLView_r (tree->headnode, glview); + fclose (glview); + + printf ("%5i c_glfaces\n", c_glfaces); +} + diff --git a/tools/quake2/extra/bsp/qbsp3/leakfile.c b/tools/quake2/extra/bsp/qbsp3/leakfile.c new file mode 100644 index 00000000..53d48375 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/leakfile.c @@ -0,0 +1,100 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +/* +============================================================================== + +LEAF FILE GENERATION + +Save out name.line for qe3 to read +============================================================================== +*/ + + +/* +============= +LeakFile + +Finds the shortest possible chain of portals +that leads from the outside leaf to a specifically +occupied leaf +============= +*/ +void LeakFile (tree_t *tree) +{ + vec3_t mid; + FILE *linefile; + char filename[1024]; + node_t *node; + int count; + + if (!tree->outside_node.occupied) + return; + + qprintf ("--- LeakFile ---\n"); + + // + // write the points to the file + // + sprintf (filename, "%s.lin", source); + linefile = fopen (filename, "w"); + if (!linefile) + Error ("Couldn't open %s\n", filename); + + count = 0; + node = &tree->outside_node; + while (node->occupied > 1) + { + int next; + portal_t *p, *nextportal; + node_t *nextnode; + int s; + + // find the best portal exit + next = node->occupied; + for (p=node->portals ; p ; p = p->next[!s]) + { + s = (p->nodes[0] == node); + if (p->nodes[s]->occupied + && p->nodes[s]->occupied < next) + { + nextportal = p; + nextnode = p->nodes[s]; + next = nextnode->occupied; + } + } + node = nextnode; + WindingCenter (nextportal->winding, mid); + fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]); + count++; + } + // add the occupant center + GetVectorForKey (node->occupant, "origin", mid); + + fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]); + qprintf ("%5i point linefile\n", count+1); + + fclose (linefile); +} + diff --git a/tools/quake2/extra/bsp/qbsp3/makefile b/tools/quake2/extra/bsp/qbsp3/makefile new file mode 100644 index 00000000..7368e5b1 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/makefile @@ -0,0 +1,98 @@ + +CFLAGS = -c +LDFLAGS = +ODIR = baddir + +EXEBASE = qbsp3 +EXE = $(ODIR)/qbsp3 +all: $(EXE) + +_next: + make "CFLAGS = -c -g -I../../common -DDOUBLEVEC_T" "ODIR = next" + +_irix: + make "CFLAGS = -c -Ofast=ip27 -OPT:IEEE_arithmetic=3 -I../../common -Xcpluscomm -DDOUBLEVEC_T" "LDFLAGS = -Ofast=ip27 -OPT:IEEE_arithmetic=3" "ODIR = irix" + +_irixdebug: + make "CFLAGS = -c -O2 -g -I../../common -Xcpluscomm -DDOUBLEVEC_T" "LDFLAGS = -g" "ODIR = irix" + +_irixinst: + make "CFLAGS = -c -Ofast=ip27 -OPT:IEEE_arithmetic=3 -I../../common -Xcpluscomm -DDOUBLEVEC_T" "LDFLAGS = -Ofast=ip27 -OPT:IEEE_arithmetic=3" "ODIR = irix" + cp irix/$(EXEBASE) /limbo/quake2/bin_irix + +_irixclean: + rm -f irix/*.o irix/$(EXEBASE) + +_osf: + make "CFLAGS = -c -O4 -I../../common -threads -DDOUBLEVEC_T" "LDFLAGS = -threads" "ODIR = osf" + +clean: + rm -f irix/*.o irix/$(EXEBASE) + +install: + cp irix/$(EXEBASE) /limbo/quake2/bin_irix + + +FILES = $(ODIR)/brushbsp.o $(ODIR)/bspfile.o $(ODIR)/cmdlib.o $(ODIR)/faces.o $(ODIR)/nodraw.o $(ODIR)/glfile.o $(ODIR)/leakfile.o $(ODIR)/map.o $(ODIR)/mathlib.o $(ODIR)/polylib.o $(ODIR)/portals.o $(ODIR)/prtfile.o $(ODIR)/qbsp3.o $(ODIR)/scriplib.o $(ODIR)/textures.o $(ODIR)/threads.o $(ODIR)/tree.o $(ODIR)/writebsp.o $(ODIR)/csg.o + +$(EXE) : $(FILES) + cc -o $(EXE) $(LDFLAGS) $(FILES) -lm + +$(ODIR)/brushbsp.o : brushbsp.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/faces.o : faces.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/nodraw.o : nodraw.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/glfile.o : glfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/leakfile.o : leakfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/map.o : map.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/portals.o : portals.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/prtfile.o : prtfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/qbsp3.o : qbsp3.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/tree.o : tree.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/textures.o : textures.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/writebsp.o : writebsp.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/csg.o : csg.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i + +$(ODIR)/cmdlib.o : ../../common/cmdlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/mathlib.o : ../../common/mathlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/polylib.o : ../../common/polylib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/scriplib.o : ../../common/scriplib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/threads.o : ../../common/threads.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/bspfile.o : ../../common/bspfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i diff --git a/tools/quake2/extra/bsp/qbsp3/map.c b/tools/quake2/extra/bsp/qbsp3/map.c new file mode 100644 index 00000000..232979c7 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/map.c @@ -0,0 +1,1017 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +extern qboolean onlyents; + +int nummapbrushes; +mapbrush_t mapbrushes[MAX_MAP_BRUSHES]; + +int nummapbrushsides; +side_t brushsides[MAX_MAP_SIDES]; +brush_texture_t side_brushtextures[MAX_MAP_SIDES]; + +int nummapplanes; +plane_t mapplanes[MAX_MAP_PLANES]; + +#define PLANE_HASHES 1024 +plane_t *planehash[PLANE_HASHES]; + +vec3_t map_mins, map_maxs; + +// undefine to make plane finding use linear sort +#define USE_HASHING + +void TestExpandBrushes (void); + +int c_boxbevels; +int c_edgebevels; + +int c_areaportals; + +int c_clipbrushes; + +/* +============================================================================= + +PLANE FINDING + +============================================================================= +*/ + + +/* +================= +PlaneTypeForNormal +================= +*/ +int PlaneTypeForNormal (vec3_t normal) +{ + vec_t ax, ay, az; + +// NOTE: should these have an epsilon around 1.0? + if (normal[0] == 1.0 || normal[0] == -1.0) + return PLANE_X; + if (normal[1] == 1.0 || normal[1] == -1.0) + return PLANE_Y; + if (normal[2] == 1.0 || normal[2] == -1.0) + return PLANE_Z; + + ax = fabs(normal[0]); + ay = fabs(normal[1]); + az = fabs(normal[2]); + + if (ax >= ay && ax >= az) + return PLANE_ANYX; + if (ay >= ax && ay >= az) + return PLANE_ANYY; + return PLANE_ANYZ; +} + +/* +================ +PlaneEqual +================ +*/ +#define NORMAL_EPSILON 0.00001 +#define DIST_EPSILON 0.01 +qboolean PlaneEqual (plane_t *p, vec3_t normal, vec_t dist) +{ +#if 1 + if ( + fabs(p->normal[0] - normal[0]) < NORMAL_EPSILON + && fabs(p->normal[1] - normal[1]) < NORMAL_EPSILON + && fabs(p->normal[2] - normal[2]) < NORMAL_EPSILON + && fabs(p->dist - dist) < DIST_EPSILON ) + return true; +#else + if (p->normal[0] == normal[0] + && p->normal[1] == normal[1] + && p->normal[2] == normal[2] + && p->dist == dist) + return true; +#endif + return false; +} + +/* +================ +AddPlaneToHash +================ +*/ +void AddPlaneToHash (plane_t *p) +{ + int hash; + + hash = (int)fabs(p->dist) / 8; + hash &= (PLANE_HASHES-1); + + p->hash_chain = planehash[hash]; + planehash[hash] = p; +} + +/* +================ +CreateNewFloatPlane +================ +*/ +int CreateNewFloatPlane (vec3_t normal, vec_t dist) +{ + plane_t *p, temp; + + if (VectorLength(normal) < 0.5) + Error ("FloatPlane: bad normal"); + // create a new plane + if (nummapplanes+2 > MAX_MAP_PLANES) + Error ("MAX_MAP_PLANES"); + + p = &mapplanes[nummapplanes]; + VectorCopy (normal, p->normal); + p->dist = dist; + p->type = (p+1)->type = PlaneTypeForNormal (p->normal); + + VectorSubtract (vec3_origin, normal, (p+1)->normal); + (p+1)->dist = -dist; + + nummapplanes += 2; + + // allways put axial planes facing positive first + if (p->type < 3) + { + if (p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0) + { + // flip order + temp = *p; + *p = *(p+1); + *(p+1) = temp; + + AddPlaneToHash (p); + AddPlaneToHash (p+1); + return nummapplanes - 1; + } + } + + AddPlaneToHash (p); + AddPlaneToHash (p+1); + return nummapplanes - 2; +} + +/* +============== +SnapVector +============== +*/ +void SnapVector (vec3_t normal) +{ + int i; + + for (i=0 ; i<3 ; i++) + { + if ( fabs(normal[i] - 1) < NORMAL_EPSILON ) + { + VectorClear (normal); + normal[i] = 1; + break; + } + if ( fabs(normal[i] - -1) < NORMAL_EPSILON ) + { + VectorClear (normal); + normal[i] = -1; + break; + } + } +} + +/* +============== +SnapPlane +============== +*/ +void SnapPlane (vec3_t normal, vec_t *dist) +{ + SnapVector (normal); + + if (fabs(*dist-Q_rint(*dist)) < DIST_EPSILON) + *dist = Q_rint(*dist); +} + +/* +============= +FindFloatPlane + +============= +*/ +#ifndef USE_HASHING +int FindFloatPlane (vec3_t normal, vec_t dist) +{ + int i; + plane_t *p; + + SnapPlane (normal, &dist); + for (i=0, p=mapplanes ; ihash_chain) + { + if (PlaneEqual (p, normal, dist)) + return p-mapplanes; + } + } + + return CreateNewFloatPlane (normal, dist); +} +#endif + +/* +================ +PlaneFromPoints +================ +*/ +int PlaneFromPoints (int *p0, int *p1, int *p2) +{ + vec3_t t1, t2, normal; + vec_t dist; + + VectorSubtract (p0, p1, t1); + VectorSubtract (p2, p1, t2); + CrossProduct (t1, t2, normal); + VectorNormalize (normal, normal); + + dist = DotProduct (p0, normal); + + return FindFloatPlane (normal, dist); +} + + +//==================================================================== + + +/* +=========== +BrushContents +=========== +*/ +int BrushContents (mapbrush_t *b) +{ + int contents; + side_t *s; + int i; + int trans; + + s = &b->original_sides[0]; + contents = s->contents; + trans = texinfo[s->texinfo].flags; + for (i=1 ; inumsides ; i++, s++) + { + s = &b->original_sides[i]; + trans |= texinfo[s->texinfo].flags; + if (s->contents != contents) + { + printf ("Entity %i, Brush %i: mixed face contents\n" + , b->entitynum, b->brushnum); + break; + } + } + + // if any side is translucent, mark the contents + // and change solid to window + if ( trans & (SURF_TRANS33|SURF_TRANS66) ) + { + contents |= CONTENTS_TRANSLUCENT; + if (contents & CONTENTS_SOLID) + { + contents &= ~CONTENTS_SOLID; + contents |= CONTENTS_WINDOW; + } + } + + return contents; +} + + +//============================================================================ + +/* +================= +AddBrushBevels + +Adds any additional planes necessary to allow the brush to be expanded +against axial bounding boxes +================= +*/ +void AddBrushBevels (mapbrush_t *b) +{ + int axis, dir; + int i, j, k, l, order; + side_t sidetemp; + brush_texture_t tdtemp; + side_t *s, *s2; + vec3_t normal; + float dist; + winding_t *w, *w2; + vec3_t vec, vec2; + float d; + + // + // add the axial planes + // + order = 0; + for (axis=0 ; axis <3 ; axis++) + { + for (dir=-1 ; dir <= 1 ; dir+=2, order++) + { + // see if the plane is allready present + for (i=0, s=b->original_sides ; inumsides ; i++,s++) + { + if (mapplanes[s->planenum].normal[axis] == dir) + break; + } + + if (i == b->numsides) + { // add a new side + if (nummapbrushsides == MAX_MAP_BRUSHSIDES) + Error ("MAX_MAP_BRUSHSIDES"); + nummapbrushsides++; + b->numsides++; + VectorClear (normal); + normal[axis] = dir; + if (dir == 1) + dist = b->maxs[axis]; + else + dist = -b->mins[axis]; + s->planenum = FindFloatPlane (normal, dist); + s->texinfo = b->original_sides[0].texinfo; + s->contents = b->original_sides[0].contents; + s->bevel = true; + c_boxbevels++; + } + + // if the plane is not in it canonical order, swap it + if (i != order) + { + sidetemp = b->original_sides[order]; + b->original_sides[order] = b->original_sides[i]; + b->original_sides[i] = sidetemp; + + j = b->original_sides - brushsides; + tdtemp = side_brushtextures[j+order]; + side_brushtextures[j+order] = side_brushtextures[j+i]; + side_brushtextures[j+i] = tdtemp; + } + } + } + + // + // add the edge bevels + // + if (b->numsides == 6) + return; // pure axial + + // test the non-axial plane edges + for (i=6 ; inumsides ; i++) + { + s = b->original_sides + i; + w = s->winding; + if (!w) + continue; + for (j=0 ; jnumpoints ; j++) + { + k = (j+1)%w->numpoints; + VectorSubtract (w->p[j], w->p[k], vec); + if (VectorNormalize (vec, vec) < 0.5) + continue; + SnapVector (vec); + for (k=0 ; k<3 ; k++) + if ( vec[k] == -1 || vec[k] == 1) + break; // axial + if (k != 3) + continue; // only test non-axial edges + + // try the six possible slanted axials from this edge + for (axis=0 ; axis <3 ; axis++) + { + for (dir=-1 ; dir <= 1 ; dir+=2) + { + // construct a plane + VectorClear (vec2); + vec2[axis] = dir; + CrossProduct (vec, vec2, normal); + if (VectorNormalize (normal, normal) < 0.5) + continue; + dist = DotProduct (w->p[j], normal); + + // if all the points on all the sides are + // behind this plane, it is a proper edge bevel + for (k=0 ; knumsides ; k++) + { + // if this plane has allready been used, skip it + if (PlaneEqual (&mapplanes[b->original_sides[k].planenum] + , normal, dist) ) + break; + + w2 = b->original_sides[k].winding; + if (!w2) + continue; + for (l=0 ; lnumpoints ; l++) + { + d = DotProduct (w2->p[l], normal) - dist; + if (d > 0.1) + break; // point in front + } + if (l != w2->numpoints) + break; + } + + if (k != b->numsides) + continue; // wasn't part of the outer hull + // add this plane + if (nummapbrushsides == MAX_MAP_BRUSHSIDES) + Error ("MAX_MAP_BRUSHSIDES"); + nummapbrushsides++; + s2 = &b->original_sides[b->numsides]; + s2->planenum = FindFloatPlane (normal, dist); + s2->texinfo = b->original_sides[0].texinfo; + s2->contents = b->original_sides[0].contents; + s2->bevel = true; + c_edgebevels++; + b->numsides++; + } + } + } + } +} + + +/* +================ +MakeBrushWindings + +makes basewindigs for sides and mins / maxs for the brush +================ +*/ +qboolean MakeBrushWindings (mapbrush_t *ob) +{ + int i, j; + winding_t *w; + side_t *side; + plane_t *plane; + + ClearBounds (ob->mins, ob->maxs); + + for (i=0 ; inumsides ; i++) + { + plane = &mapplanes[ob->original_sides[i].planenum]; + w = BaseWindingForPlane (plane->normal, plane->dist); + for (j=0 ; jnumsides && w; j++) + { + if (i == j) + continue; + if (ob->original_sides[j].bevel) + continue; + plane = &mapplanes[ob->original_sides[j].planenum^1]; + ChopWindingInPlace (&w, plane->normal, plane->dist, 0); //CLIP_EPSILON); + } + + side = &ob->original_sides[i]; + side->winding = w; + if (w) + { + side->visible = true; + for (j=0 ; jnumpoints ; j++) + AddPointToBounds (w->p[j], ob->mins, ob->maxs); + } + } + + for (i=0 ; i<3 ; i++) + { + if (ob->mins[0] < -4096 || ob->maxs[0] > 4096) + printf ("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum); + if (ob->mins[0] > 4096 || ob->maxs[0] < -4096) + printf ("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum); + } + + return true; +} + + +/* +================= +ParseBrush +================= +*/ +void ParseBrush (entity_t *mapent) +{ + mapbrush_t *b; + int i,j, k; + int mt; + side_t *side, *s2; + int planenum; + brush_texture_t td; + int planepts[3][3]; + + if (nummapbrushes == MAX_MAP_BRUSHES) + Error ("nummapbrushes == MAX_MAP_BRUSHES"); + + b = &mapbrushes[nummapbrushes]; + b->original_sides = &brushsides[nummapbrushsides]; + b->entitynum = num_entities-1; + b->brushnum = nummapbrushes - mapent->firstbrush; + + do + { + if (!GetToken (true)) + break; + if (!strcmp (token, "}") ) + break; + + if (nummapbrushsides == MAX_MAP_BRUSHSIDES) + Error ("MAX_MAP_BRUSHSIDES"); + side = &brushsides[nummapbrushsides]; + + // read the three point plane definition + for (i=0 ; i<3 ; i++) + { + if (i != 0) + GetToken (true); + if (strcmp (token, "(") ) + Error ("parsing brush"); + + for (j=0 ; j<3 ; j++) + { + GetToken (false); + planepts[i][j] = atoi(token); + } + + GetToken (false); + if (strcmp (token, ")") ) + Error ("parsing brush"); + + } + + + // + // read the texturedef + // + GetToken (false); + strcpy (td.name, token); + + GetToken (false); + td.shift[0] = atoi(token); + GetToken (false); + td.shift[1] = atoi(token); + GetToken (false); + td.rotate = atoi(token); + GetToken (false); + td.scale[0] = atof(token); + GetToken (false); + td.scale[1] = atof(token); + + // find default flags and values + mt = FindMiptex (td.name); + td.flags = textureref[mt].flags; + td.value = textureref[mt].value; + side->contents = textureref[mt].contents; + side->surf = td.flags = textureref[mt].flags; + + if (TokenAvailable()) + { + GetToken (false); + side->contents = atoi(token); + GetToken (false); + side->surf = td.flags = atoi(token); + GetToken (false); + td.value = atoi(token); + } + + // translucent objects are automatically classified as detail + if (side->surf & (SURF_TRANS33|SURF_TRANS66) ) + side->contents |= CONTENTS_DETAIL; + if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) + side->contents |= CONTENTS_DETAIL; + if (fulldetail) + side->contents &= ~CONTENTS_DETAIL; + if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1) + | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) ) + side->contents |= CONTENTS_SOLID; + + // hints and skips are never detail, and have no content + if (side->surf & (SURF_HINT|SURF_SKIP) ) + { + side->contents = 0; + side->surf &= ~CONTENTS_DETAIL; + } + + + // + // find the plane number + // + planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]); + if (planenum == -1) + { + printf ("Entity %i, Brush %i: plane with no normal\n" + , b->entitynum, b->brushnum); + continue; + } + + // + // see if the plane has been used already + // + for (k=0 ; knumsides ; k++) + { + s2 = b->original_sides + k; + if (s2->planenum == planenum) + { + printf ("Entity %i, Brush %i: duplicate plane\n" + , b->entitynum, b->brushnum); + break; + } + if ( s2->planenum == (planenum^1) ) + { + printf ("Entity %i, Brush %i: mirrored plane\n" + , b->entitynum, b->brushnum); + break; + } + } + if (k != b->numsides) + continue; // duplicated + + // + // keep this side + // + + side = b->original_sides + b->numsides; + side->planenum = planenum; + side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum], + &td, vec3_origin); + + // save the td off in case there is an origin brush and we + // have to recalculate the texinfo + side_brushtextures[nummapbrushsides] = td; + + nummapbrushsides++; + b->numsides++; + } while (1); + + // get the content for the entire brush + b->contents = BrushContents (b); + + // allow detail brushes to be removed + if (nodetail && (b->contents & CONTENTS_DETAIL) ) + { + b->numsides = 0; + return; + } + + // allow water brushes to be removed + if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) ) + { + b->numsides = 0; + return; + } + + // create windings for sides and bounds for brush + MakeBrushWindings (b); + + // brushes that will not be visible at all will never be + // used as bsp splitters + if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) + { + c_clipbrushes++; + for (i=0 ; inumsides ; i++) + b->original_sides[i].texinfo = TEXINFO_NODE; + } + + // + // origin brushes are removed, but they set + // the rotation origin for the rest of the brushes + // in the entity. After the entire entity is parsed, + // the planenums and texinfos will be adjusted for + // the origin brush + // + if (b->contents & CONTENTS_ORIGIN) + { + char string[32]; + vec3_t origin; + + if (num_entities == 1) + { + Error ("Entity %i, Brush %i: origin brushes not allowed in world" + , b->entitynum, b->brushnum); + return; + } + + VectorAdd (b->mins, b->maxs, origin); + VectorScale (origin, 0.5, origin); + + sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); + SetKeyValue (&entities[b->entitynum], "origin", string); + + VectorCopy (origin, entities[b->entitynum].origin); + + // don't keep this brush + b->numsides = 0; + + return; + } + + AddBrushBevels (b); + + nummapbrushes++; + mapent->numbrushes++; +} + +/* +================ +MoveBrushesToWorld + +Takes all of the brushes from the current entity and +adds them to the world's brush list. + +Used by func_group and func_areaportal +================ +*/ +void MoveBrushesToWorld (entity_t *mapent) +{ + int newbrushes; + int worldbrushes; + mapbrush_t *temp; + int i; + + // this is pretty gross, because the brushes are expected to be + // in linear order for each entity + + newbrushes = mapent->numbrushes; + worldbrushes = entities[0].numbrushes; + + temp = malloc(newbrushes*sizeof(mapbrush_t)); + memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(mapbrush_t)); + +#if 0 // let them keep their original brush numbers + for (i=0 ; inumbrushes = 0; +} + +/* +================ +ParseMapEntity +================ +*/ +qboolean ParseMapEntity (void) +{ + entity_t *mapent; + epair_t *e; + side_t *s; + int i, j; + int startbrush, startsides; + vec_t newdist; + mapbrush_t *b; + + if (!GetToken (true)) + return false; + + if (strcmp (token, "{") ) + Error ("ParseEntity: { not found"); + + if (num_entities == MAX_MAP_ENTITIES) + Error ("num_entities == MAX_MAP_ENTITIES"); + + startbrush = nummapbrushes; + startsides = nummapbrushsides; + + mapent = &entities[num_entities]; + num_entities++; + memset (mapent, 0, sizeof(*mapent)); + mapent->firstbrush = nummapbrushes; + mapent->numbrushes = 0; +// mapent->portalareas[0] = -1; +// mapent->portalareas[1] = -1; + + do + { + if (!GetToken (true)) + Error ("ParseEntity: EOF without closing brace"); + if (!strcmp (token, "}") ) + break; + if (!strcmp (token, "{") ) + ParseBrush (mapent); + else + { + e = ParseEpair (); + e->next = mapent->epairs; + mapent->epairs = e; + } + } while (1); + + GetVectorForKey (mapent, "origin", mapent->origin); + + // + // if there was an origin brush, offset all of the planes and texinfo + // + if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2]) + { + for (i=0 ; inumbrushes ; i++) + { + b = &mapbrushes[mapent->firstbrush + i]; + for (j=0 ; jnumsides ; j++) + { + s = &b->original_sides[j]; + newdist = mapplanes[s->planenum].dist - + DotProduct (mapplanes[s->planenum].normal, mapent->origin); + s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist); + s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum], + &side_brushtextures[s-brushsides], mapent->origin); + } + MakeBrushWindings (b); + } + } + + // group entities are just for editor convenience + // toss all brushes into the world entity + if (!strcmp ("func_group", ValueForKey (mapent, "classname"))) + { + MoveBrushesToWorld (mapent); + mapent->numbrushes = 0; + return true; + } + + // areaportal entities move their brushes, but don't eliminate + // the entity + if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname"))) + { + char str[128]; + + if (mapent->numbrushes != 1) + Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1); + + b = &mapbrushes[nummapbrushes-1]; + b->contents = CONTENTS_AREAPORTAL; + c_areaportals++; + mapent->areaportalnum = c_areaportals; + // set the portal number as "style" + sprintf (str, "%i", c_areaportals); + SetKeyValue (mapent, "style", str); + MoveBrushesToWorld (mapent); + return true; + } + + return true; +} + +//=================================================================== + +/* +================ +LoadMapFile +================ +*/ +void LoadMapFile (char *filename) +{ + int i; + + qprintf ("--- LoadMapFile ---\n"); + + LoadScriptFile (filename); + + nummapbrushsides = 0; + num_entities = 0; + + while (ParseMapEntity ()) + { + } + + ClearBounds (map_mins, map_maxs); + for (i=0 ; i 4096) + continue; // no valid points + AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs); + AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs); + } + + qprintf ("%5i brushes\n", nummapbrushes); + qprintf ("%5i clipbrushes\n", c_clipbrushes); + qprintf ("%5i total sides\n", nummapbrushsides); + qprintf ("%5i boxbevels\n", c_boxbevels); + qprintf ("%5i edgebevels\n", c_edgebevels); + qprintf ("%5i entities\n", num_entities); + qprintf ("%5i planes\n", nummapplanes); + qprintf ("%5i areaportals\n", c_areaportals); + qprintf ("size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", map_mins[0],map_mins[1],map_mins[2], + map_maxs[0],map_maxs[1],map_maxs[2]); + +// TestExpandBrushes (); +} + + +//==================================================================== + + +/* +================ +TestExpandBrushes + +Expands all the brush planes and saves a new map out +================ +*/ +void TestExpandBrushes (void) +{ + FILE *f; + side_t *s; + int i, j, bn; + winding_t *w; + char *name = "expanded.map"; + mapbrush_t *brush; + vec_t dist; + + printf ("writing %s\n", name); + f = fopen (name, "wb"); + if (!f) + Error ("Can't write %s\b", name); + + fprintf (f, "{\n\"classname\" \"worldspawn\"\n"); + + for (bn=0 ; bnnumsides ; i++) + { + s = brush->original_sides + i; + dist = mapplanes[s->planenum].dist; + for (j=0 ; j<3 ; j++) + dist += fabs( 16 * mapplanes[s->planenum].normal[j] ); + + w = BaseWindingForPlane (mapplanes[s->planenum].normal, dist); + + fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]); + fprintf (f,"( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]); + fprintf (f,"( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]); + + fprintf (f, "%s 0 0 0 1 1\n", texinfo[s->texinfo].texture); + FreeWinding (w); + } + fprintf (f, "}\n"); + } + fprintf (f, "}\n"); + + fclose (f); + + Error ("can't proceed after expanding brushes"); +} diff --git a/tools/quake2/extra/bsp/qbsp3/nodraw.c b/tools/quake2/extra/bsp/qbsp3/nodraw.c new file mode 100644 index 00000000..fd6959d8 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/nodraw.c @@ -0,0 +1,47 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +vec3_t draw_mins, draw_maxs; +qboolean drawflag; + +void Draw_ClearWindow (void) +{ +} + +//============================================================ + +#define GLSERV_PORT 25001 + + +void GLS_BeginScene (void) +{ +} + +void GLS_Winding (winding_t *w, int code) +{ +} + +void GLS_EndScene (void) +{ +} diff --git a/tools/quake2/extra/bsp/qbsp3/portals.c b/tools/quake2/extra/bsp/qbsp3/portals.c new file mode 100644 index 00000000..ef57caef --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/portals.c @@ -0,0 +1,1111 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + + +int c_active_portals; +int c_peak_portals; +int c_boundary; +int c_boundary_sides; + +/* +=========== +AllocPortal +=========== +*/ +portal_t *AllocPortal (void) +{ + portal_t *p; + + if (numthreads == 1) + c_active_portals++; + if (c_active_portals > c_peak_portals) + c_peak_portals = c_active_portals; + + p = malloc (sizeof(portal_t)); + memset (p, 0, sizeof(portal_t)); + + return p; +} + +void FreePortal (portal_t *p) +{ + if (p->winding) + FreeWinding (p->winding); + if (numthreads == 1) + c_active_portals--; + free (p); +} + +//============================================================== + +/* +============== +VisibleContents + +Returns the single content bit of the +strongest visible content present +============== +*/ +int VisibleContents (int contents) +{ + int i; + + for (i=1 ; i<=LAST_VISIBLE_CONTENTS ; i<<=1) + if (contents & i ) + return i; + + return 0; +} + + +/* +=============== +ClusterContents +=============== +*/ +int ClusterContents (node_t *node) +{ + int c1, c2, c; + + if (node->planenum == PLANENUM_LEAF) + return node->contents; + + c1 = ClusterContents(node->children[0]); + c2 = ClusterContents(node->children[1]); + c = c1|c2; + + // a cluster may include some solid detail areas, but + // still be seen into + if ( ! (c1&CONTENTS_SOLID) || ! (c2&CONTENTS_SOLID) ) + c &= ~CONTENTS_SOLID; + return c; +} + +/* +============= +Portal_VisFlood + +Returns true if the portal is empty or translucent, allowing +the PVS calculation to see through it. +The nodes on either side of the portal may actually be clusters, +not leafs, so all contents should be ored together +============= +*/ +qboolean Portal_VisFlood (portal_t *p) +{ + int c1, c2; + + if (!p->onnode) + return false; // to global outsideleaf + + c1 = ClusterContents(p->nodes[0]); + c2 = ClusterContents(p->nodes[1]); + + if (!VisibleContents (c1^c2)) + return true; + + if (c1 & (CONTENTS_TRANSLUCENT|CONTENTS_DETAIL)) + c1 = 0; + if (c2 & (CONTENTS_TRANSLUCENT|CONTENTS_DETAIL)) + c2 = 0; + + if ( (c1|c2) & CONTENTS_SOLID ) + return false; // can't see through solid + + if (! (c1 ^ c2)) + return true; // identical on both sides + + if (!VisibleContents (c1^c2)) + return true; + return false; +} + + +/* +=============== +Portal_EntityFlood + +The entity flood determines which areas are +"outside" on the map, which are then filled in. +Flowing from side s to side !s +=============== +*/ +qboolean Portal_EntityFlood (portal_t *p, int s) +{ + if (p->nodes[0]->planenum != PLANENUM_LEAF + || p->nodes[1]->planenum != PLANENUM_LEAF) + Error ("Portal_EntityFlood: not a leaf"); + + // can never cross to a solid + if ( (p->nodes[0]->contents & CONTENTS_SOLID) + || (p->nodes[1]->contents & CONTENTS_SOLID) ) + return false; + + // can flood through everything else + return true; +} + + +//============================================================================= + +int c_tinyportals; + +/* +============= +AddPortalToNodes +============= +*/ +void AddPortalToNodes (portal_t *p, node_t *front, node_t *back) +{ + if (p->nodes[0] || p->nodes[1]) + Error ("AddPortalToNode: allready included"); + + p->nodes[0] = front; + p->next[0] = front->portals; + front->portals = p; + + p->nodes[1] = back; + p->next[1] = back->portals; + back->portals = p; +} + + +/* +============= +RemovePortalFromNode +============= +*/ +void RemovePortalFromNode (portal_t *portal, node_t *l) +{ + portal_t **pp, *t; + +// remove reference to the current portal + pp = &l->portals; + while (1) + { + t = *pp; + if (!t) + Error ("RemovePortalFromNode: portal not in leaf"); + + if ( t == portal ) + break; + + if (t->nodes[0] == l) + pp = &t->next[0]; + else if (t->nodes[1] == l) + pp = &t->next[1]; + else + Error ("RemovePortalFromNode: portal not bounding leaf"); + } + + if (portal->nodes[0] == l) + { + *pp = portal->next[0]; + portal->nodes[0] = NULL; + } + else if (portal->nodes[1] == l) + { + *pp = portal->next[1]; + portal->nodes[1] = NULL; + } +} + +//============================================================================ + +void PrintPortal (portal_t *p) +{ + int i; + winding_t *w; + + w = p->winding; + for (i=0 ; inumpoints ; i++) + printf ("(%5.0f,%5.0f,%5.0f)\n",w->p[i][0] + , w->p[i][1], w->p[i][2]); +} + +/* +================ +MakeHeadnodePortals + +The created portals will face the global outside_node +================ +*/ +#define SIDESPACE 8 +void MakeHeadnodePortals (tree_t *tree) +{ + vec3_t bounds[2]; + int i, j, n; + portal_t *p, *portals[6]; + plane_t bplanes[6], *pl; + node_t *node; + + node = tree->headnode; + +// pad with some space so there will never be null volume leafs + for (i=0 ; i<3 ; i++) + { + bounds[0][i] = tree->mins[i] - SIDESPACE; + bounds[1][i] = tree->maxs[i] + SIDESPACE; + } + + tree->outside_node.planenum = PLANENUM_LEAF; + tree->outside_node.brushlist = NULL; + tree->outside_node.portals = NULL; + tree->outside_node.contents = 0; + + for (i=0 ; i<3 ; i++) + for (j=0 ; j<2 ; j++) + { + n = j*3 + i; + + p = AllocPortal (); + portals[n] = p; + + pl = &bplanes[n]; + memset (pl, 0, sizeof(*pl)); + if (j) + { + pl->normal[i] = -1; + pl->dist = -bounds[j][i]; + } + else + { + pl->normal[i] = 1; + pl->dist = bounds[j][i]; + } + p->plane = *pl; + p->winding = BaseWindingForPlane (pl->normal, pl->dist); + AddPortalToNodes (p, node, &tree->outside_node); + } + +// clip the basewindings by all the other planes + for (i=0 ; i<6 ; i++) + { + for (j=0 ; j<6 ; j++) + { + if (j == i) + continue; + ChopWindingInPlace (&portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON); + } + } +} + +//=================================================== + + +/* +================ +BaseWindingForNode +================ +*/ +#define BASE_WINDING_EPSILON 0.001 +#define SPLIT_WINDING_EPSILON 0.001 + +winding_t *BaseWindingForNode (node_t *node) +{ + winding_t *w; + node_t *n; + plane_t *plane; + vec3_t normal; + vec_t dist; + + w = BaseWindingForPlane (mapplanes[node->planenum].normal + , mapplanes[node->planenum].dist); + + // clip by all the parents + for (n=node->parent ; n && w ; ) + { + plane = &mapplanes[n->planenum]; + + if (n->children[0] == node) + { // take front + ChopWindingInPlace (&w, plane->normal, plane->dist, BASE_WINDING_EPSILON); + } + else + { // take back + VectorSubtract (vec3_origin, plane->normal, normal); + dist = -plane->dist; + ChopWindingInPlace (&w, normal, dist, BASE_WINDING_EPSILON); + } + node = n; + n = n->parent; + } + + return w; +} + +//============================================================ + +qboolean WindingIsTiny (winding_t *w); + +/* +================== +MakeNodePortal + +create the new portal by taking the full plane winding for the cutting plane +and clipping it by all of parents of this node +================== +*/ +void MakeNodePortal (node_t *node) +{ + portal_t *new_portal, *p; + winding_t *w; + vec3_t normal; + float dist; + int side; + + w = BaseWindingForNode (node); + + // clip the portal by all the other portals in the node + for (p = node->portals ; p && w; p = p->next[side]) + { + if (p->nodes[0] == node) + { + side = 0; + VectorCopy (p->plane.normal, normal); + dist = p->plane.dist; + } + else if (p->nodes[1] == node) + { + side = 1; + VectorSubtract (vec3_origin, p->plane.normal, normal); + dist = -p->plane.dist; + } + else + Error ("CutNodePortals_r: mislinked portal"); + + ChopWindingInPlace (&w, normal, dist, 0.1); + } + + if (!w) + { + return; + } + + if (WindingIsTiny (w)) + { + c_tinyportals++; + FreeWinding (w); + return; + } + + + new_portal = AllocPortal (); + new_portal->plane = mapplanes[node->planenum]; + new_portal->onnode = node; + new_portal->winding = w; + AddPortalToNodes (new_portal, node->children[0], node->children[1]); +} + + +/* +============== +SplitNodePortals + +Move or split the portals that bound node so that the node's +children have portals instead of node. +============== +*/ +void SplitNodePortals (node_t *node) +{ + portal_t *p, *next_portal, *new_portal; + node_t *f, *b, *other_node; + int side; + plane_t *plane; + winding_t *frontwinding, *backwinding; + + plane = &mapplanes[node->planenum]; + f = node->children[0]; + b = node->children[1]; + + for (p = node->portals ; p ; p = next_portal) + { + if (p->nodes[0] == node) + side = 0; + else if (p->nodes[1] == node) + side = 1; + else + Error ("CutNodePortals_r: mislinked portal"); + next_portal = p->next[side]; + + other_node = p->nodes[!side]; + RemovePortalFromNode (p, p->nodes[0]); + RemovePortalFromNode (p, p->nodes[1]); + +// +// cut the portal into two portals, one on each side of the cut plane +// + ClipWindingEpsilon (p->winding, plane->normal, plane->dist, + SPLIT_WINDING_EPSILON, &frontwinding, &backwinding); + + if (frontwinding && WindingIsTiny(frontwinding)) + { + FreeWinding (frontwinding); + frontwinding = NULL; + c_tinyportals++; + } + + if (backwinding && WindingIsTiny(backwinding)) + { + FreeWinding (backwinding); + backwinding = NULL; + c_tinyportals++; + } + + if (!frontwinding && !backwinding) + { // tiny windings on both sides + continue; + } + + if (!frontwinding) + { + FreeWinding (backwinding); + if (side == 0) + AddPortalToNodes (p, b, other_node); + else + AddPortalToNodes (p, other_node, b); + continue; + } + if (!backwinding) + { + FreeWinding (frontwinding); + if (side == 0) + AddPortalToNodes (p, f, other_node); + else + AddPortalToNodes (p, other_node, f); + continue; + } + + // the winding is split + new_portal = AllocPortal (); + *new_portal = *p; + new_portal->winding = backwinding; + FreeWinding (p->winding); + p->winding = frontwinding; + + if (side == 0) + { + AddPortalToNodes (p, f, other_node); + AddPortalToNodes (new_portal, b, other_node); + } + else + { + AddPortalToNodes (p, other_node, f); + AddPortalToNodes (new_portal, other_node, b); + } + } + + node->portals = NULL; +} + + +/* +================ +CalcNodeBounds +================ +*/ +void CalcNodeBounds (node_t *node) +{ + portal_t *p; + int s; + int i; + + // calc mins/maxs for both leafs and nodes + ClearBounds (node->mins, node->maxs); + for (p = node->portals ; p ; p = p->next[s]) + { + s = (p->nodes[1] == node); + for (i=0 ; iwinding->numpoints ; i++) + AddPointToBounds (p->winding->p[i], node->mins, node->maxs); + } +} + + +/* +================== +MakeTreePortals_r +================== +*/ +void MakeTreePortals_r (node_t *node) +{ + int i; + + CalcNodeBounds (node); + if (node->mins[0] >= node->maxs[0]) + { + printf ("WARNING: node without a volume\n"); + } + + for (i=0 ; i<3 ; i++) + { + if (node->mins[i] < -8000 || node->maxs[i] > 8000) + { + printf ("WARNING: node with unbounded volume\n"); + break; + } + } + if (node->planenum == PLANENUM_LEAF) + return; + + MakeNodePortal (node); + SplitNodePortals (node); + + MakeTreePortals_r (node->children[0]); + MakeTreePortals_r (node->children[1]); +} + +/* +================== +MakeTreePortals +================== +*/ +void MakeTreePortals (tree_t *tree) +{ + MakeHeadnodePortals (tree); + MakeTreePortals_r (tree->headnode); +} + +/* +========================================================= + +FLOOD ENTITIES + +========================================================= +*/ + +/* +============= +FloodPortals_r +============= +*/ +void FloodPortals_r (node_t *node, int dist) +{ + portal_t *p; + int s; + + node->occupied = dist; + + for (p=node->portals ; p ; p = p->next[s]) + { + s = (p->nodes[1] == node); + + if (p->nodes[!s]->occupied) + continue; + + if (!Portal_EntityFlood (p, s)) + continue; + + FloodPortals_r (p->nodes[!s], dist+1); + } +} + +/* +============= +PlaceOccupant +============= +*/ +qboolean PlaceOccupant (node_t *headnode, vec3_t origin, entity_t *occupant) +{ + node_t *node; + vec_t d; + plane_t *plane; + + // find the leaf to start in + node = headnode; + while (node->planenum != PLANENUM_LEAF) + { + plane = &mapplanes[node->planenum]; + d = DotProduct (origin, plane->normal) - plane->dist; + if (d >= 0) + node = node->children[0]; + else + node = node->children[1]; + } + + if (node->contents == CONTENTS_SOLID) + return false; + node->occupant = occupant; + + FloodPortals_r (node, 1); + + return true; +} + +/* +============= +FloodEntities + +Marks all nodes that can be reached by entites +============= +*/ +qboolean FloodEntities (tree_t *tree) +{ + int i; + vec3_t origin; + char *cl; + qboolean inside; + node_t *headnode; + + headnode = tree->headnode; + qprintf ("--- FloodEntities ---\n"); + inside = false; + tree->outside_node.occupied = 0; + + for (i=1 ; ioutside_node.occupied) + { + qprintf ("entity reached from outside -- no filling\n"); + } + + return (qboolean)(inside && !tree->outside_node.occupied); +} + +/* +========================================================= + +FLOOD AREAS + +========================================================= +*/ + +int c_areas; + +/* +============= +FloodAreas_r +============= +*/ +void FloodAreas_r (node_t *node) +{ + portal_t *p; + int s; + bspbrush_t *b; + entity_t *e; + + if (node->contents == CONTENTS_AREAPORTAL) + { + // this node is part of an area portal + b = node->brushlist; + e = &entities[b->original->entitynum]; + + // if the current area has allready touched this + // portal, we are done + if (e->portalareas[0] == c_areas || e->portalareas[1] == c_areas) + return; + + // note the current area as bounding the portal + if (e->portalareas[1]) + { + printf ("WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum); + return; + } + if (e->portalareas[0]) + e->portalareas[1] = c_areas; + else + e->portalareas[0] = c_areas; + + return; + } + + if (node->area) + return; // allready got it + node->area = c_areas; + + for (p=node->portals ; p ; p = p->next[s]) + { + s = (p->nodes[1] == node); +#if 0 + if (p->nodes[!s]->occupied) + continue; +#endif + if (!Portal_EntityFlood (p, s)) + continue; + + FloodAreas_r (p->nodes[!s]); + } +} + +/* +============= +FindAreas_r + +Just decend the tree, and for each node that hasn't had an +area set, flood fill out from there +============= +*/ +void FindAreas_r (node_t *node) +{ + if (node->planenum != PLANENUM_LEAF) + { + FindAreas_r (node->children[0]); + FindAreas_r (node->children[1]); + return; + } + + if (node->area) + return; // allready got it + + if (node->contents & CONTENTS_SOLID) + return; + + if (!node->occupied) + return; // not reachable by entities + + // area portals are allways only flooded into, never + // out of + if (node->contents == CONTENTS_AREAPORTAL) + return; + + c_areas++; + FloodAreas_r (node); +} + +/* +============= +SetAreaPortalAreas_r + +Just decend the tree, and for each node that hasn't had an +area set, flood fill out from there +============= +*/ +void SetAreaPortalAreas_r (node_t *node) +{ + bspbrush_t *b; + entity_t *e; + + if (node->planenum != PLANENUM_LEAF) + { + SetAreaPortalAreas_r (node->children[0]); + SetAreaPortalAreas_r (node->children[1]); + return; + } + + if (node->contents == CONTENTS_AREAPORTAL) + { + if (node->area) + return; // allready set + + b = node->brushlist; + e = &entities[b->original->entitynum]; + node->area = e->portalareas[0]; + if (!e->portalareas[1]) + { + printf ("WARNING: areaportal entity %i doesn't touch two areas\n", b->original->entitynum); + return; + } + } +} + +/* +============= +EmitAreaPortals + +============= +*/ +void EmitAreaPortals (node_t *headnode) +{ + int i, j; + entity_t *e; + dareaportal_t *dp; + + if (c_areas > MAX_MAP_AREAS) + Error ("MAX_MAP_AREAS"); + numareas = c_areas+1; + numareaportals = 1; // leave 0 as an error + + for (i=1 ; i<=c_areas ; i++) + { + dareas[i].firstareaportal = numareaportals; + for (j=0 ; jareaportalnum) + continue; + dp = &dareaportals[numareaportals]; + if (e->portalareas[0] == i) + { + dp->portalnum = e->areaportalnum; + dp->otherarea = e->portalareas[1]; + numareaportals++; + } + else if (e->portalareas[1] == i) + { + dp->portalnum = e->areaportalnum; + dp->otherarea = e->portalareas[0]; + numareaportals++; + } + } + dareas[i].numareaportals = numareaportals - dareas[i].firstareaportal; + } + + qprintf ("%5i numareas\n", numareas); + qprintf ("%5i numareaportals\n", numareaportals); +} + +/* +============= +FloodAreas + +Mark each leaf with an area, bounded by CONTENTS_AREAPORTAL +============= +*/ +void FloodAreas (tree_t *tree) +{ + qprintf ("--- FloodAreas ---\n"); + FindAreas_r (tree->headnode); + SetAreaPortalAreas_r (tree->headnode); + qprintf ("%5i areas\n", c_areas); +} + +//====================================================== + +int c_outside; +int c_inside; +int c_solid; + +void FillOutside_r (node_t *node) +{ + if (node->planenum != PLANENUM_LEAF) + { + FillOutside_r (node->children[0]); + FillOutside_r (node->children[1]); + return; + } + + // anything not reachable by an entity + // can be filled away + if (!node->occupied) + { + if (node->contents != CONTENTS_SOLID) + { + c_outside++; + node->contents = CONTENTS_SOLID; + } + else + c_solid++; + } + else + c_inside++; + +} + +/* +============= +FillOutside + +Fill all nodes that can't be reached by entities +============= +*/ +void FillOutside (node_t *headnode) +{ + c_outside = 0; + c_inside = 0; + c_solid = 0; + qprintf ("--- FillOutside ---\n"); + FillOutside_r (headnode); + qprintf ("%5i solid leafs\n", c_solid); + qprintf ("%5i leafs filled\n", c_outside); + qprintf ("%5i inside leafs\n", c_inside); +} + + +//============================================================== + +/* +============ +FindPortalSide + +Finds a brush side to use for texturing the given portal +============ +*/ +void FindPortalSide (portal_t *p) +{ + int viscontents; + bspbrush_t *bb; + mapbrush_t *brush; + node_t *n; + int i,j; + int planenum; + side_t *side, *bestside; + float dot, bestdot; + plane_t *p1, *p2; + + // decide which content change is strongest + // solid > lava > water, etc + viscontents = VisibleContents (p->nodes[0]->contents ^ p->nodes[1]->contents); + if (!viscontents) + return; + + planenum = p->onnode->planenum; + bestside = NULL; + bestdot = 0; + + for (j=0 ; j<2 ; j++) + { + n = p->nodes[j]; + p1 = &mapplanes[p->onnode->planenum]; + for (bb=n->brushlist ; bb ; bb=bb->next) + { + brush = bb->original; + if ( !(brush->contents & viscontents) ) + continue; + for (i=0 ; inumsides ; i++) + { + side = &brush->original_sides[i]; + if (side->bevel) + continue; + if (side->texinfo == TEXINFO_NODE) + continue; // non-visible + if ((side->planenum&~1) == planenum) + { // exact match + bestside = &brush->original_sides[i]; + goto gotit; + } + // see how close the match is + p2 = &mapplanes[side->planenum&~1]; + dot = DotProduct (p1->normal, p2->normal); + if (dot > bestdot) + { + bestdot = dot; + bestside = side; + } + } + } + } + +gotit: + if (!bestside) + qprintf ("WARNING: side not found for portal\n"); + + p->sidefound = true; + p->side = bestside; +} + + +/* +=============== +MarkVisibleSides_r + +=============== +*/ +void MarkVisibleSides_r (node_t *node) +{ + portal_t *p; + int s; + + if (node->planenum != PLANENUM_LEAF) + { + MarkVisibleSides_r (node->children[0]); + MarkVisibleSides_r (node->children[1]); + return; + } + + // empty leafs are never boundary leafs + if (!node->contents) + return; + + // see if there is a visible face + for (p=node->portals ; p ; p = p->next[!s]) + { + s = (p->nodes[0] == node); + if (!p->onnode) + continue; // edge of world + if (!p->sidefound) + FindPortalSide (p); + if (p->side) + p->side->visible = true; + } + +} + +/* +============= +MarkVisibleSides + +============= +*/ +void MarkVisibleSides (tree_t *tree, int startbrush, int endbrush) +{ + int i, j; + mapbrush_t *mb; + int numsides; + + qprintf ("--- MarkVisibleSides ---\n"); + + // clear all the visible flags + for (i=startbrush ; inumsides; + for (j=0 ; joriginal_sides[j].visible = false; + } + + // set visible flags on the sides that are used by portals + MarkVisibleSides_r (tree->headnode); +} + diff --git a/tools/quake2/extra/bsp/qbsp3/prtfile.c b/tools/quake2/extra/bsp/qbsp3/prtfile.c new file mode 100644 index 00000000..2a5b08f4 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/prtfile.c @@ -0,0 +1,287 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +/* +============================================================================== + +PORTAL FILE GENERATION + +Save out name.prt for qvis to read +============================================================================== +*/ + + +#define PORTALFILE "PRT1" + +FILE *pf; +int num_visclusters; // clusters the player can be in +int num_visportals; + +void WriteFloat (FILE *f, vec_t v) +{ + if ( fabs(v - Q_rint(v)) < 0.001 ) + fprintf (f,"%i ",(int)Q_rint(v)); + else + fprintf (f,"%f ",v); +} + +/* +================= +WritePortalFile_r +================= +*/ +void WritePortalFile_r (node_t *node) +{ + int i, s; + portal_t *p; + winding_t *w; + vec3_t normal; + vec_t dist; + + // decision node + if (node->planenum != PLANENUM_LEAF && !node->detail_seperator) + { + WritePortalFile_r (node->children[0]); + WritePortalFile_r (node->children[1]); + return; + } + + if (node->contents & CONTENTS_SOLID) + return; + + for (p = node->portals ; p ; p=p->next[s]) + { + w = p->winding; + s = (p->nodes[1] == node); + if (w && p->nodes[0] == node) + { + if (!Portal_VisFlood (p)) + continue; + // write out to the file + + // sometimes planes get turned around when they are very near + // the changeover point between different axis. interpret the + // plane the same way vis will, and flip the side orders if needed + // FIXME: is this still relevent? + WindingPlane (w, normal, &dist); + if ( DotProduct (p->plane.normal, normal) < 0.99 ) + { // backwards... + fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster); + } + else + fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster); + for (i=0 ; inumpoints ; i++) + { + fprintf (pf,"("); + WriteFloat (pf, w->p[i][0]); + WriteFloat (pf, w->p[i][1]); + WriteFloat (pf, w->p[i][2]); + fprintf (pf,") "); + } + fprintf (pf,"\n"); + } + } + +} + +/* +================ +FillLeafNumbers_r + +All of the leafs under node will have the same cluster +================ +*/ +void FillLeafNumbers_r (node_t *node, int num) +{ + if (node->planenum == PLANENUM_LEAF) + { + if (node->contents & CONTENTS_SOLID) + node->cluster = -1; + else + node->cluster = num; + return; + } + node->cluster = num; + FillLeafNumbers_r (node->children[0], num); + FillLeafNumbers_r (node->children[1], num); +} + +/* +================ +NumberLeafs_r +================ +*/ +void NumberLeafs_r (node_t *node) +{ + portal_t *p; + + if (node->planenum != PLANENUM_LEAF && !node->detail_seperator) + { // decision node + node->cluster = -99; + NumberLeafs_r (node->children[0]); + NumberLeafs_r (node->children[1]); + return; + } + + // either a leaf or a detail cluster + + if ( node->contents & CONTENTS_SOLID ) + { // solid block, viewpoint never inside + node->cluster = -1; + return; + } + + FillLeafNumbers_r (node, num_visclusters); + num_visclusters++; + + // count the portals + for (p = node->portals ; p ; ) + { + if (p->nodes[0] == node) // only write out from first leaf + { + if (Portal_VisFlood (p)) + num_visportals++; + p = p->next[0]; + } + else + p = p->next[1]; + } + +} + + +/* +================ +CreateVisPortals_r +================ +*/ +void CreateVisPortals_r (node_t *node) +{ + // stop as soon as we get to a detail_seperator, which + // means that everything below is in a single cluster + if (node->planenum == PLANENUM_LEAF || node->detail_seperator ) + return; + + MakeNodePortal (node); + SplitNodePortals (node); + + CreateVisPortals_r (node->children[0]); + CreateVisPortals_r (node->children[1]); +} + +/* +================ +FinishVisPortals_r +================ +*/ +void FinishVisPortals2_r (node_t *node) +{ + if (node->planenum == PLANENUM_LEAF) + return; + + MakeNodePortal (node); + SplitNodePortals (node); + + FinishVisPortals2_r (node->children[0]); + FinishVisPortals2_r (node->children[1]); +} + +void FinishVisPortals_r (node_t *node) +{ + if (node->planenum == PLANENUM_LEAF) + return; + + if (node->detail_seperator) + { + FinishVisPortals2_r (node); + return; + } + + FinishVisPortals_r (node->children[0]); + FinishVisPortals_r (node->children[1]); +} + + +int clusterleaf; +void SaveClusters_r (node_t *node) +{ + if (node->planenum == PLANENUM_LEAF) + { + dleafs[clusterleaf++].cluster = node->cluster; + return; + } + SaveClusters_r (node->children[0]); + SaveClusters_r (node->children[1]); +} + +/* +================ +WritePortalFile +================ +*/ +void WritePortalFile (tree_t *tree) +{ + char filename[1024]; + node_t *headnode; + + qprintf ("--- WritePortalFile ---\n"); + + headnode = tree->headnode; + num_visclusters = 0; + num_visportals = 0; + + FreeTreePortals_r (headnode); + + MakeHeadnodePortals (tree); + + CreateVisPortals_r (headnode); + +// set the cluster field in every leaf and count the total number of portals + + NumberLeafs_r (headnode); + +// write the file + sprintf (filename, "%s.prt", source); + printf ("writing %s\n", filename); + pf = fopen (filename, "w"); + if (!pf) + Error ("Error opening %s", filename); + + fprintf (pf, "%s\n", PORTALFILE); + fprintf (pf, "%i\n", num_visclusters); + fprintf (pf, "%i\n", num_visportals); + + qprintf ("%5i visclusters\n", num_visclusters); + qprintf ("%5i visportals\n", num_visportals); + + WritePortalFile_r (headnode); + + fclose (pf); + + // we need to store the clusters out now because ordering + // issues made us do this after writebsp... + clusterleaf = 1; + SaveClusters_r (headnode); +} + diff --git a/tools/quake2/extra/bsp/qbsp3/qbsp.h b/tools/quake2/extra/bsp/qbsp3/qbsp.h new file mode 100644 index 00000000..af032e43 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/qbsp.h @@ -0,0 +1,355 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "cmdlib.h" +#include "mathlib.h" +#include "scriplib.h" +#include "polylib.h" +#include "threads.h" +#include "bspfile.h" + +#define MAX_BRUSH_SIDES 128 +#define CLIP_EPSILON 0.1 + +#define BOGUS_RANGE 8192 + +#define TEXINFO_NODE -1 // side is allready on a node + +typedef struct plane_s +{ + vec3_t normal; + vec_t dist; + int type; + struct plane_s *hash_chain; +} plane_t; + +typedef struct +{ + vec_t shift[2]; + vec_t rotate; + vec_t scale[2]; + char name[32]; + int flags; + int value; +} brush_texture_t; + +typedef struct side_s +{ + int planenum; + int texinfo; + winding_t *winding; + struct side_s *original; // bspbrush_t sides will reference the mapbrush_t sides + int contents; // from miptex + int surf; // from miptex + qboolean visible; // choose visble planes first + qboolean tested; // this plane allready checked as a split + qboolean bevel; // don't ever use for bsp splitting +} side_t; + +typedef struct brush_s +{ + int entitynum; + int brushnum; + + int contents; + + vec3_t mins, maxs; + + int numsides; + side_t *original_sides; +} mapbrush_t; + +#define PLANENUM_LEAF -1 + +#define MAXEDGES 20 + +typedef struct face_s +{ + struct face_s *next; // on node + + // the chain of faces off of a node can be merged or split, + // but each face_t along the way will remain in the chain + // until the entire tree is freed + struct face_s *merged; // if set, this face isn't valid anymore + struct face_s *split[2]; // if set, this face isn't valid anymore + + struct portal_s *portal; + int texinfo; + int planenum; + int contents; // faces in different contents can't merge + int outputnumber; + winding_t *w; + int numpoints; + qboolean badstartvert; // tjunctions cannot be fixed without a midpoint vertex + int vertexnums[MAXEDGES]; +} face_t; + + + +typedef struct bspbrush_s +{ + struct bspbrush_s *next; + vec3_t mins, maxs; + int side, testside; // side of node during construction + mapbrush_t *original; + int numsides; + side_t sides[6]; // variably sized +} bspbrush_t; + + + +#define MAX_NODE_BRUSHES 8 +typedef struct node_s +{ + // both leafs and nodes + int planenum; // -1 = leaf node + struct node_s *parent; + vec3_t mins, maxs; // valid after portalization + bspbrush_t *volume; // one for each leaf/node + + // nodes only + qboolean detail_seperator; // a detail brush caused the split + side_t *side; // the side that created the node + struct node_s *children[2]; + face_t *faces; + + // leafs only + bspbrush_t *brushlist; // fragments of all brushes in this leaf + int contents; // OR of all brush contents + int occupied; // 1 or greater can reach entity + entity_t *occupant; // for leak file testing + int cluster; // for portalfile writing + int area; // for areaportals + struct portal_s *portals; // also on nodes during construction +} node_t; + +typedef struct portal_s +{ + plane_t plane; + node_t *onnode; // NULL = outside box + node_t *nodes[2]; // [0] = front side of plane + struct portal_s *next[2]; + winding_t *winding; + + qboolean sidefound; // false if ->side hasn't been checked + side_t *side; // NULL = non-visible + face_t *face[2]; // output face in bsp file +} portal_t; + +typedef struct +{ + node_t *headnode; + node_t outside_node; + vec3_t mins, maxs; +} tree_t; + +extern int entity_num; + +extern plane_t mapplanes[MAX_MAP_PLANES]; +extern int nummapplanes; + +extern int nummapbrushes; +extern mapbrush_t mapbrushes[MAX_MAP_BRUSHES]; + +extern vec3_t map_mins, map_maxs; + +#define MAX_MAP_SIDES (MAX_MAP_BRUSHES*6) + +extern int nummapbrushsides; +extern side_t brushsides[MAX_MAP_SIDES]; + +extern qboolean noprune; +extern qboolean nodetail; +extern qboolean fulldetail; +extern qboolean nomerge; +extern qboolean nosubdiv; +extern qboolean nowater; +extern qboolean noweld; +extern qboolean noshare; +extern qboolean notjunc; + +extern vec_t microvolume; + +extern char outbase[32]; + +extern char source[1024]; + +void LoadMapFile (char *filename); +int FindFloatPlane (vec3_t normal, vec_t dist); + +//============================================================================= + +// textures.c + +typedef struct +{ + char name[64]; + int flags; + int value; + int contents; + char animname[64]; +} textureref_t; + +#define MAX_MAP_TEXTURES 1024 + +extern textureref_t textureref[MAX_MAP_TEXTURES]; + +int FindMiptex (char *name); + +int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin); + +//============================================================================= + +void FindGCD (int *v); + +mapbrush_t *Brush_LoadEntity (entity_t *ent); +int PlaneTypeForNormal (vec3_t normal); +qboolean MakeBrushPlanes (mapbrush_t *b); +int FindIntPlane (int *inormal, int *iorigin); +void CreateBrush (int brushnum); + + +//============================================================================= + +// draw.c + +extern vec3_t draw_mins, draw_maxs; +extern qboolean drawflag; + +void Draw_ClearWindow (void); +void DrawWinding (winding_t *w); + +void GLS_BeginScene (void); +void GLS_Winding (winding_t *w, int code); +void GLS_EndScene (void); + +//============================================================================= + +// csg + +bspbrush_t *MakeBspBrushList (int startbrush, int endbrush, + vec3_t clipmins, vec3_t clipmaxs); +bspbrush_t *ChopBrushes (bspbrush_t *head); +bspbrush_t *InitialBrushList (bspbrush_t *list); +bspbrush_t *OptimizedBrushList (bspbrush_t *list); + +void WriteBrushMap (char *name, bspbrush_t *list); + +//============================================================================= + +// brushbsp + +void WriteBrushList (char *name, bspbrush_t *brush, qboolean onlyvis); + +bspbrush_t *CopyBrush (bspbrush_t *brush); + +void SplitBrush (bspbrush_t *brush, int planenum, + bspbrush_t **front, bspbrush_t **back); + +tree_t *AllocTree (void); +node_t *AllocNode (void); +bspbrush_t *AllocBrush (int numsides); +int CountBrushList (bspbrush_t *brushes); +void FreeBrush (bspbrush_t *brushes); +vec_t BrushVolume (bspbrush_t *brush); + +void BoundBrush (bspbrush_t *brush); +void FreeBrushList (bspbrush_t *brushes); + +tree_t *BrushBSP (bspbrush_t *brushlist, vec3_t mins, vec3_t maxs); + +//============================================================================= + +// portals.c + +int VisibleContents (int contents); + +void MakeHeadnodePortals (tree_t *tree); +void MakeNodePortal (node_t *node); +void SplitNodePortals (node_t *node); + +qboolean Portal_VisFlood (portal_t *p); + +qboolean FloodEntities (tree_t *tree); +void FillOutside (node_t *headnode); +void FloodAreas (tree_t *tree); +void MarkVisibleSides (tree_t *tree, int start, int end); +void FreePortal (portal_t *p); +void EmitAreaPortals (node_t *headnode); + +void MakeTreePortals (tree_t *tree); + +//============================================================================= + +// glfile.c + +void OutputWinding (winding_t *w, FILE *glview); +void WriteGLView (tree_t *tree, char *source); + +//============================================================================= + +// leakfile.c + +void LeakFile (tree_t *tree); + +//============================================================================= + +// prtfile.c + +void WritePortalFile (tree_t *tree); + +//============================================================================= + +// writebsp.c + +void SetModelNumbers (void); +void SetLightStyles (void); + +void BeginBSPFile (void); +void WriteBSP (node_t *headnode); +void EndBSPFile (void); +void BeginModel (void); +void EndModel (void); + +//============================================================================= + +// faces.c + +void MakeFaces (node_t *headnode); +void FixTjuncs (node_t *headnode); +int GetEdge2 (int v1, int v2, face_t *f); + +face_t *AllocFace (void); +void FreeFace (face_t *f); + +void MergeNodeFaces (node_t *node); + +//============================================================================= + +// tree.c + +void FreeTree (tree_t *tree); +void FreeTree_r (node_t *node); +void PrintTree_r (node_t *node, int depth); +void FreeTreePortals_r (node_t *node); +void PruneNodes_r (node_t *node); +void PruneNodes (node_t *node); diff --git a/tools/quake2/extra/bsp/qbsp3/qbsp3.c b/tools/quake2/extra/bsp/qbsp3/qbsp3.c new file mode 100644 index 00000000..1cc5b907 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/qbsp3.c @@ -0,0 +1,537 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qbsp.h" + +extern float subdivide_size; + +char source[1024]; +char name[1024]; + +vec_t microvolume = 1.0; +qboolean noprune; +qboolean glview; +qboolean nodetail; +qboolean fulldetail; +qboolean onlyents; +qboolean nomerge; +qboolean nowater; +qboolean nofill; +qboolean nocsg; +qboolean noweld; +qboolean noshare; +qboolean nosubdiv; +qboolean notjunc; +qboolean noopt; +qboolean leaktest; +qboolean verboseentities; + +char outbase[32]; + +int block_xl = -8, block_xh = 7, block_yl = -8, block_yh = 7; + +int entity_num; + + +node_t *block_nodes[10][10]; + +/* +============ +BlockTree + +============ +*/ +node_t *BlockTree (int xl, int yl, int xh, int yh) +{ + node_t *node; + vec3_t normal; + float dist; + int mid; + + if (xl == xh && yl == yh) + { + node = block_nodes[xl+5][yl+5]; + if (!node) + { // return an empty leaf + node = AllocNode (); + node->planenum = PLANENUM_LEAF; + node->contents = 0; //CONTENTS_SOLID; + return node; + } + return node; + } + + // create a seperator along the largest axis + node = AllocNode (); + + if (xh - xl > yh - yl) + { // split x axis + mid = xl + (xh-xl)/2 + 1; + normal[0] = 1; + normal[1] = 0; + normal[2] = 0; + dist = mid*1024; + node->planenum = FindFloatPlane (normal, dist); + node->children[0] = BlockTree ( mid, yl, xh, yh); + node->children[1] = BlockTree ( xl, yl, mid-1, yh); + } + else + { + mid = yl + (yh-yl)/2 + 1; + normal[0] = 0; + normal[1] = 1; + normal[2] = 0; + dist = mid*1024; + node->planenum = FindFloatPlane (normal, dist); + node->children[0] = BlockTree ( xl, mid, xh, yh); + node->children[1] = BlockTree ( xl, yl, xh, mid-1); + } + + return node; +} + +/* +============ +ProcessBlock_Thread + +============ +*/ +int brush_start, brush_end; +void ProcessBlock_Thread (int blocknum) +{ + int xblock, yblock; + vec3_t mins, maxs; + bspbrush_t *brushes; + tree_t *tree; + node_t *node; + + yblock = block_yl + blocknum / (block_xh-block_xl+1); + xblock = block_xl + blocknum % (block_xh-block_xl+1); + + qprintf ("############### block %2i,%2i ###############\n", xblock, yblock); + + mins[0] = xblock*1024; + mins[1] = yblock*1024; + mins[2] = -4096; + maxs[0] = (xblock+1)*1024; + maxs[1] = (yblock+1)*1024; + maxs[2] = 4096; + + // the makelist and chopbrushes could be cached between the passes... + brushes = MakeBspBrushList (brush_start, brush_end, mins, maxs); + if (!brushes) + { + node = AllocNode (); + node->planenum = PLANENUM_LEAF; + node->contents = CONTENTS_SOLID; + block_nodes[xblock+5][yblock+5] = node; + return; + } + + if (!nocsg) + brushes = ChopBrushes (brushes); + + tree = BrushBSP (brushes, mins, maxs); + + block_nodes[xblock+5][yblock+5] = tree->headnode; +} + +/* +============ +ProcessWorldModel + +============ +*/ +void ProcessWorldModel (void) +{ + entity_t *e; + tree_t *tree; + qboolean leaked; + qboolean optimize; + + e = &entities[entity_num]; + + brush_start = e->firstbrush; + brush_end = brush_start + e->numbrushes; + leaked = false; + + // + // perform per-block operations + // + if (block_xh * 1024 > map_maxs[0]) + block_xh = floor(map_maxs[0]/1024.0); + if ( (block_xl+1) * 1024 < map_mins[0]) + block_xl = floor(map_mins[0]/1024.0); + if (block_yh * 1024 > map_maxs[1]) + block_yh = floor(map_maxs[1]/1024.0); + if ( (block_yl+1) * 1024 < map_mins[1]) + block_yl = floor(map_mins[1]/1024.0); + + if (block_xl <-4) + block_xl = -4; + if (block_yl <-4) + block_yl = -4; + if (block_xh > 3) + block_xh = 3; + if (block_yh > 3) + block_yh = 3; + + for (optimize = false ; optimize <= true ; optimize++) + { + qprintf ("--------------------------------------------\n"); + + RunThreadsOnIndividual ((block_xh-block_xl+1)*(block_yh-block_yl+1), + !verbose, ProcessBlock_Thread); + + // + // build the division tree + // oversizing the blocks guarantees that all the boundaries + // will also get nodes. + // + + qprintf ("--------------------------------------------\n"); + + tree = AllocTree (); + tree->headnode = BlockTree (block_xl-1, block_yl-1, block_xh+1, block_yh+1); + + tree->mins[0] = (block_xl)*1024; + tree->mins[1] = (block_yl)*1024; + tree->mins[2] = map_mins[2] - 8; + + tree->maxs[0] = (block_xh+1)*1024; + tree->maxs[1] = (block_yh+1)*1024; + tree->maxs[2] = map_maxs[2] + 8; + + // + // perform the global operations + // + MakeTreePortals (tree); + + if (FloodEntities (tree)) + FillOutside (tree->headnode); + else + { + printf ("**** leaked ****\n"); + leaked = true; + LeakFile (tree); + if (leaktest) + { + printf ("--- MAP LEAKED ---\n"); + exit (0); + } + } + + MarkVisibleSides (tree, brush_start, brush_end); + if (noopt || leaked) + break; + if (!optimize) + { + FreeTree (tree); + } + } + + FloodAreas (tree); + if (glview) + WriteGLView (tree, source); + MakeFaces (tree->headnode); + FixTjuncs (tree->headnode); + + if (!noprune) + PruneNodes (tree->headnode); + + WriteBSP (tree->headnode); + + if (!leaked) + WritePortalFile (tree); + + FreeTree (tree); +} + +/* +============ +ProcessSubModel + +============ +*/ +void ProcessSubModel (void) +{ + entity_t *e; + int start, end; + tree_t *tree; + bspbrush_t *list; + vec3_t mins, maxs; + + e = &entities[entity_num]; + + start = e->firstbrush; + end = start + e->numbrushes; + + mins[0] = mins[1] = mins[2] = -4096; + maxs[0] = maxs[1] = maxs[2] = 4096; + list = MakeBspBrushList (start, end, mins, maxs); + if (!nocsg) + list = ChopBrushes (list); + tree = BrushBSP (list, mins, maxs); + MakeTreePortals (tree); + MarkVisibleSides (tree, start, end); + MakeFaces (tree->headnode); + FixTjuncs (tree->headnode); + WriteBSP (tree->headnode); + FreeTree (tree); +} + +/* +============ +ProcessModels +============ +*/ +void ProcessModels (void) +{ + BeginBSPFile (); + + for (entity_num=0 ; entity_num< num_entities ; entity_num++) + { + if (!entities[entity_num].numbrushes) + continue; + + qprintf ("############### model %i ###############\n", nummodels); + BeginModel (); + if (entity_num == 0) + ProcessWorldModel (); + else + ProcessSubModel (); + EndModel (); + + if (!verboseentities) + verbose = false; // don't bother printing submodels + } + + EndBSPFile (); +} + + +/* +============ +main +============ +*/ +int main (int argc, char **argv) +{ + int i; + double start, end; + char path[1024]; + + printf ("---- qbsp3 ----\n"); + + for (i=1 ; ivalue); + textureref[i].flags = LittleLong (mt->flags); + textureref[i].contents = LittleLong (mt->contents); + strcpy (textureref[i].animname, mt->animname); + free (mt); + } + nummiptex++; + + if (textureref[i].animname[0]) + FindMiptex (textureref[i].animname); + + return i; +} + + +/* +================== +textureAxisFromPlane +================== +*/ +vec3_t baseaxis[18] = +{ +{0,0,1}, {1,0,0}, {0,-1,0}, // floor +{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling +{1,0,0}, {0,1,0}, {0,0,-1}, // west wall +{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall +{0,1,0}, {1,0,0}, {0,0,-1}, // south wall +{0,-1,0}, {1,0,0}, {0,0,-1} // north wall +}; + +void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv) +{ + int bestaxis; + vec_t dot,best; + int i; + + best = 0; + bestaxis = 0; + + for (i=0 ; i<6 ; i++) + { + dot = DotProduct (pln->normal, baseaxis[i*3]); + if (dot > best) + { + best = dot; + bestaxis = i; + } + } + + VectorCopy (baseaxis[bestaxis*3+1], xv); + VectorCopy (baseaxis[bestaxis*3+2], yv); +} + + + + +int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin) +{ + vec3_t vecs[2]; + int sv, tv; + vec_t ang, sinv, cosv; + vec_t ns, nt; + texinfo_t tx, *tc; + int i, j, k; + float shift[2]; + brush_texture_t anim; + int mt; + + if (!bt->name[0]) + return 0; + + memset (&tx, 0, sizeof(tx)); + strcpy (tx.texture, bt->name); + + TextureAxisFromPlane(plane, vecs[0], vecs[1]); + + shift[0] = DotProduct (origin, vecs[0]); + shift[1] = DotProduct (origin, vecs[1]); + + if (!bt->scale[0]) + bt->scale[0] = 1; + if (!bt->scale[1]) + bt->scale[1] = 1; + + +// rotate axis + if (bt->rotate == 0) + { sinv = 0 ; cosv = 1; } + else if (bt->rotate == 90) + { sinv = 1 ; cosv = 0; } + else if (bt->rotate == 180) + { sinv = 0 ; cosv = -1; } + else if (bt->rotate == 270) + { sinv = -1 ; cosv = 0; } + else + { + ang = bt->rotate / 180 * Q_PI; + sinv = sin(ang); + cosv = cos(ang); + } + + if (vecs[0][0]) + sv = 0; + else if (vecs[0][1]) + sv = 1; + else + sv = 2; + + if (vecs[1][0]) + tv = 0; + else if (vecs[1][1]) + tv = 1; + else + tv = 2; + + for (i=0 ; i<2 ; i++) + { + ns = cosv * vecs[i][sv] - sinv * vecs[i][tv]; + nt = sinv * vecs[i][sv] + cosv * vecs[i][tv]; + vecs[i][sv] = ns; + vecs[i][tv] = nt; + } + + for (i=0 ; i<2 ; i++) + for (j=0 ; j<3 ; j++) + tx.vecs[i][j] = vecs[i][j] / bt->scale[i]; + + tx.vecs[0][3] = bt->shift[0] + shift[0]; + tx.vecs[1][3] = bt->shift[1] + shift[1]; + tx.flags = bt->flags; + tx.value = bt->value; + + // + // find the texinfo + // + tc = texinfo; + for (i=0 ; iflags != tx.flags) + continue; + if (tc->value != tx.value) + continue; + for (j=0 ; j<2 ; j++) + { + if (strcmp (tc->texture, tx.texture)) + goto skip; + for (k=0 ; k<4 ; k++) + { + if (tc->vecs[j][k] != tx.vecs[j][k]) + goto skip; + } + } + return i; +skip:; + } + *tc = tx; + numtexinfo++; + + // load the next animation + mt = FindMiptex (bt->name); + if (textureref[mt].animname[0]) + { + anim = *bt; + strcpy (anim.name, textureref[mt].animname); + tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin); + } + else + tc->nexttexinfo = -1; + + + return i; +} diff --git a/tools/quake2/extra/bsp/qbsp3/tree.c b/tools/quake2/extra/bsp/qbsp3/tree.c new file mode 100644 index 00000000..a6c1f34c --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/tree.c @@ -0,0 +1,219 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +#include "qbsp.h" + +extern int c_nodes; + +void RemovePortalFromNode (portal_t *portal, node_t *l); + +node_t *NodeForPoint (node_t *node, vec3_t origin) +{ + plane_t *plane; + vec_t d; + + while (node->planenum != PLANENUM_LEAF) + { + plane = &mapplanes[node->planenum]; + d = DotProduct (origin, plane->normal) - plane->dist; + if (d >= 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return node; +} + + + +/* +============= +FreeTreePortals_r +============= +*/ +void FreeTreePortals_r (node_t *node) +{ + portal_t *p, *nextp; + int s; + + // free children + if (node->planenum != PLANENUM_LEAF) + { + FreeTreePortals_r (node->children[0]); + FreeTreePortals_r (node->children[1]); + } + + // free portals + for (p=node->portals ; p ; p=nextp) + { + s = (p->nodes[1] == node); + nextp = p->next[s]; + + RemovePortalFromNode (p, p->nodes[!s]); + FreePortal (p); + } + node->portals = NULL; +} + +/* +============= +FreeTree_r +============= +*/ +void FreeTree_r (node_t *node) +{ + face_t *f, *nextf; + + // free children + if (node->planenum != PLANENUM_LEAF) + { + FreeTree_r (node->children[0]); + FreeTree_r (node->children[1]); + } + + // free bspbrushes + FreeBrushList (node->brushlist); + + // free faces + for (f=node->faces ; f ; f=nextf) + { + nextf = f->next; + FreeFace (f); + } + + // free the node + if (node->volume) + FreeBrush (node->volume); + + if (numthreads == 1) + c_nodes--; + free (node); +} + + +/* +============= +FreeTree +============= +*/ +void FreeTree (tree_t *tree) +{ + FreeTreePortals_r (tree->headnode); + FreeTree_r (tree->headnode); + free (tree); +} + +//=============================================================== + +void PrintTree_r (node_t *node, int depth) +{ + int i; + plane_t *plane; + bspbrush_t *bb; + + for (i=0 ; iplanenum == PLANENUM_LEAF) + { + if (!node->brushlist) + printf ("NULL\n"); + else + { + for (bb=node->brushlist ; bb ; bb=bb->next) + printf ("%i ", bb->original->brushnum); + printf ("\n"); + } + return; + } + + plane = &mapplanes[node->planenum]; + printf ("#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum, + plane->normal[0], plane->normal[1], plane->normal[2], + plane->dist); + PrintTree_r (node->children[0], depth+1); + PrintTree_r (node->children[1], depth+1); +} + +/* +========================================================= + +NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED + +========================================================= +*/ + +int c_pruned; + +/* +============ +PruneNodes_r +============ +*/ +void PruneNodes_r (node_t *node) +{ + bspbrush_t *b, *next; + + if (node->planenum == PLANENUM_LEAF) + return; + PruneNodes_r (node->children[0]); + PruneNodes_r (node->children[1]); + + if ( (node->children[0]->contents & CONTENTS_SOLID) + && (node->children[1]->contents & CONTENTS_SOLID) ) + { + if (node->faces) + Error ("node->faces seperating CONTENTS_SOLID"); + if (node->children[0]->faces || node->children[1]->faces) + Error ("!node->faces with children"); + + // FIXME: free stuff + node->planenum = PLANENUM_LEAF; + node->contents = CONTENTS_SOLID; + node->detail_seperator = false; + + if (node->brushlist) + Error ("PruneNodes: node->brushlist"); + + // combine brush lists + node->brushlist = node->children[1]->brushlist; + + for (b=node->children[0]->brushlist ; b ; b=next) + { + next = b->next; + b->next = node->brushlist; + node->brushlist = b; + } + + c_pruned++; + } +} + + +void PruneNodes (node_t *node) +{ + qprintf ("--- PruneNodes ---\n"); + c_pruned = 0; + PruneNodes_r (node); + qprintf ("%5i pruned nodes\n", c_pruned); +} + +//=========================================================== diff --git a/tools/quake2/extra/bsp/qbsp3/writebsp.c b/tools/quake2/extra/bsp/qbsp3/writebsp.c new file mode 100644 index 00000000..cc5c3266 --- /dev/null +++ b/tools/quake2/extra/bsp/qbsp3/writebsp.c @@ -0,0 +1,590 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +#include "qbsp.h" + +int c_nofaces; +int c_facenodes; + + +/* +========================================================= + +ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES + +========================================================= +*/ + +int planeused[MAX_MAP_PLANES]; + +/* +============ +EmitPlanes + +There is no oportunity to discard planes, because all of the original +brushes will be saved in the map. +============ +*/ +void EmitPlanes (void) +{ + int i; + dplane_t *dp; + plane_t *mp; + int planetranslate[MAX_MAP_PLANES]; + + mp = mapplanes; + for (i=0 ; inormal, dp->normal); + dp->dist = mp->dist; + dp->type = mp->type; + numplanes++; + } +} + + +//======================================================== + +void EmitMarkFace (dleaf_t *leaf_p, face_t *f) +{ + int i; + int facenum; + + while (f->merged) + f = f->merged; + + if (f->split[0]) + { + EmitMarkFace (leaf_p, f->split[0]); + EmitMarkFace (leaf_p, f->split[1]); + return; + } + + facenum = f->outputnumber; + if (facenum == -1) + return; // degenerate face + + if (facenum < 0 || facenum >= numfaces) + Error ("Bad leafface"); + for (i=leaf_p->firstleafface ; i= MAX_MAP_LEAFFACES) + Error ("MAX_MAP_LEAFFACES"); + + dleaffaces[numleaffaces] = facenum; + numleaffaces++; + } + +} + + +/* +================== +EmitLeaf +================== +*/ +void EmitLeaf (node_t *node) +{ + dleaf_t *leaf_p; + portal_t *p; + int s; + face_t *f; + bspbrush_t *b; + int i; + int brushnum; + + // emit a leaf + if (numleafs >= MAX_MAP_LEAFS) + Error ("MAX_MAP_LEAFS"); + + leaf_p = &dleafs[numleafs]; + numleafs++; + + leaf_p->contents = node->contents; + leaf_p->cluster = node->cluster; + leaf_p->area = node->area; + + // + // write bounding box info + // + VectorCopy (node->mins, leaf_p->mins); + VectorCopy (node->maxs, leaf_p->maxs); + + // + // write the leafbrushes + // + leaf_p->firstleafbrush = numleafbrushes; + for (b=node->brushlist ; b ; b=b->next) + { + if (numleafbrushes >= MAX_MAP_LEAFBRUSHES) + Error ("MAX_MAP_LEAFBRUSHES"); + + brushnum = b->original - mapbrushes; + for (i=leaf_p->firstleafbrush ; inumleafbrushes = numleafbrushes - leaf_p->firstleafbrush; + + // + // write the leaffaces + // + if (leaf_p->contents & CONTENTS_SOLID) + return; // no leaffaces in solids + + leaf_p->firstleafface = numleaffaces; + + for (p = node->portals ; p ; p = p->next[s]) + { + s = (p->nodes[1] == node); + f = p->face[s]; + if (!f) + continue; // not a visible portal + + EmitMarkFace (leaf_p, f); + } + + leaf_p->numleaffaces = numleaffaces - leaf_p->firstleafface; +} + + +/* +================== +EmitFace +================== +*/ +void EmitFace (face_t *f) +{ + dface_t *df; + int i; + int e; + + f->outputnumber = -1; + + if (f->numpoints < 3) + { + return; // degenerated + } + if (f->merged || f->split[0] || f->split[1]) + { + return; // not a final face + } + + // save output number so leaffaces can use + f->outputnumber = numfaces; + + if (numfaces >= MAX_MAP_FACES) + Error ("numfaces == MAX_MAP_FACES"); + df = &dfaces[numfaces]; + numfaces++; + + // planenum is used by qlight, but not quake + df->planenum = f->planenum & (~1); + df->side = f->planenum & 1; + + df->firstedge = numsurfedges; + df->numedges = f->numpoints; + df->texinfo = f->texinfo; + for (i=0 ; inumpoints ; i++) + { +// e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f); + e = GetEdge2 (f->vertexnums[i], f->vertexnums[(i+1)%f->numpoints], f); + if (numsurfedges >= MAX_MAP_SURFEDGES) + Error ("numsurfedges == MAX_MAP_SURFEDGES"); + dsurfedges[numsurfedges] = e; + numsurfedges++; + } +} + +/* +============ +EmitDrawingNode_r +============ +*/ +int EmitDrawNode_r (node_t *node) +{ + dnode_t *n; + face_t *f; + int i; + + if (node->planenum == PLANENUM_LEAF) + { + EmitLeaf (node); + return -numleafs; + } + + // emit a node + if (numnodes == MAX_MAP_NODES) + Error ("MAX_MAP_NODES"); + n = &dnodes[numnodes]; + numnodes++; + + VectorCopy (node->mins, n->mins); + VectorCopy (node->maxs, n->maxs); + + planeused[node->planenum]++; + planeused[node->planenum^1]++; + + if (node->planenum & 1) + Error ("WriteDrawNodes_r: odd planenum"); + n->planenum = node->planenum; + n->firstface = numfaces; + + if (!node->faces) + c_nofaces++; + else + c_facenodes++; + + for (f=node->faces ; f ; f=f->next) + EmitFace (f); + + n->numfaces = numfaces - n->firstface; + + + // + // recursively output the other nodes + // + for (i=0 ; i<2 ; i++) + { + if (node->children[i]->planenum == PLANENUM_LEAF) + { + n->children[i] = -(numleafs + 1); + EmitLeaf (node->children[i]); + } + else + { + n->children[i] = numnodes; + EmitDrawNode_r (node->children[i]); + } + } + + return n - dnodes; +} + +//========================================================= + + +/* +============ +WriteBSP +============ +*/ +void WriteBSP (node_t *headnode) +{ + int oldfaces; + + c_nofaces = 0; + c_facenodes = 0; + + qprintf ("--- WriteBSP ---\n"); + + oldfaces = numfaces; + dmodels[nummodels].headnode = EmitDrawNode_r (headnode); + EmitAreaPortals (headnode); + + qprintf ("%5i nodes with faces\n", c_facenodes); + qprintf ("%5i nodes without faces\n", c_nofaces); + qprintf ("%5i faces\n", numfaces-oldfaces); +} + +//=========================================================== + +/* +============ +SetModelNumbers +============ +*/ +void SetModelNumbers (void) +{ + int i; + int models; + char value[10]; + + models = 1; + for (i=1 ; icontents = b->contents; + db->firstside = numbrushsides; + db->numsides = b->numsides; + for (j=0 ; jnumsides ; j++) + { + if (numbrushsides == MAX_MAP_BRUSHSIDES) + Error ("MAX_MAP_BRUSHSIDES"); + cp = &dbrushsides[numbrushsides]; + numbrushsides++; + cp->planenum = b->original_sides[j].planenum; + cp->texinfo = b->original_sides[j].texinfo; + } + + // add any axis planes not contained in the brush to bevel off corners + for (x=0 ; x<3 ; x++) + for (s=-1 ; s<=1 ; s+=2) + { + // add the plane + VectorCopy (vec3_origin, normal); + normal[x] = s; + if (s == -1) + dist = -b->mins[x]; + else + dist = b->maxs[x]; + planenum = FindFloatPlane (normal, dist); + for (i=0 ; inumsides ; i++) + if (b->original_sides[i].planenum == planenum) + break; + if (i == b->numsides) + { + if (numbrushsides >= MAX_MAP_BRUSHSIDES) + Error ("MAX_MAP_BRUSHSIDES"); + + dbrushsides[numbrushsides].planenum = planenum; + dbrushsides[numbrushsides].texinfo = + dbrushsides[numbrushsides-1].texinfo; + numbrushsides++; + db->numsides++; + } + } + + } + +} + +//=========================================================== + +/* +================== +BeginBSPFile +================== +*/ +void BeginBSPFile (void) +{ + // these values may actually be initialized + // if the file existed when loaded, so clear them explicitly + nummodels = 0; + numfaces = 0; + numnodes = 0; + numbrushsides = 0; + numvertexes = 0; + numleaffaces = 0; + numleafbrushes = 0; + numsurfedges = 0; + + // edge 0 is not used, because 0 can't be negated + numedges = 1; + + // leave vertex 0 as an error + numvertexes = 1; + + // leave leaf 0 as an error + numleafs = 1; + dleafs[0].contents = CONTENTS_SOLID; +} + + +/* +============ +EndBSPFile +============ +*/ +void EndBSPFile (void) +{ + char path[1024]; + int len; + byte *buf; + + + EmitBrushes (); + EmitPlanes (); + UnparseEntities (); + + // load the pop +#if 0 + sprintf (path, "%s/pics/pop.lmp", gamedir); + len = LoadFile (path, &buf); + memcpy (dpop, buf, sizeof(dpop)); + free (buf); +#endif + + // write the map + sprintf (path, "%s.bsp", source); + printf ("Writing %s\n", path); + WriteBSPFile (path); +} + + +/* +================== +BeginModel +================== +*/ +int firstmodleaf; +extern int firstmodeledge; +extern int firstmodelface; +void BeginModel (void) +{ + dmodel_t *mod; + int start, end; + mapbrush_t *b; + int j; + entity_t *e; + vec3_t mins, maxs; + + if (nummodels == MAX_MAP_MODELS) + Error ("MAX_MAP_MODELS"); + mod = &dmodels[nummodels]; + + mod->firstface = numfaces; + + firstmodleaf = numleafs; + firstmodeledge = numedges; + firstmodelface = numfaces; + + // + // bound the brushes + // + e = &entities[entity_num]; + + start = e->firstbrush; + end = start + e->numbrushes; + ClearBounds (mins, maxs); + + for (j=start ; jnumsides) + continue; // not a real brush (origin brush) + AddPointToBounds (b->mins, mins, maxs); + AddPointToBounds (b->maxs, mins, maxs); + } + + VectorCopy (mins, mod->mins); + VectorCopy (maxs, mod->maxs); +} + + +/* +================== +EndModel +================== +*/ +void EndModel (void) +{ + dmodel_t *mod; + + mod = &dmodels[nummodels]; + + mod->numfaces = numfaces - mod->firstface; + + nummodels++; +} + diff --git a/tools/quake2/extra/bsp/qrad3/lightmap.c b/tools/quake2/extra/bsp/qrad3/lightmap.c new file mode 100644 index 00000000..e6a5aaaa --- /dev/null +++ b/tools/quake2/extra/bsp/qrad3/lightmap.c @@ -0,0 +1,1316 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +#include "qrad.h" + +#define MAX_LSTYLES 256 + +typedef struct +{ + dface_t *faces[2]; + qboolean coplanar; +} edgeshare_t; + +edgeshare_t edgeshare[MAX_MAP_EDGES]; + +int facelinks[MAX_MAP_FACES]; +int planelinks[2][MAX_MAP_PLANES]; + +/* +============ +LinkPlaneFaces +============ +*/ +void LinkPlaneFaces (void) +{ + int i; + dface_t *f; + + f = dfaces; + for (i=0 ; iside][f->planenum]; + planelinks[f->side][f->planenum] = i; + } +} + +/* +============ +PairEdges +============ +*/ +void PairEdges (void) +{ + int i, j, k; + dface_t *f; + edgeshare_t *e; + + f = dfaces; + for (i=0 ; inumedges ; j++) + { + k = dsurfedges[f->firstedge + j]; + if (k < 0) + { + e = &edgeshare[-k]; + e->faces[1] = f; + } + else + { + e = &edgeshare[k]; + e->faces[0] = f; + } + + if (e->faces[0] && e->faces[1]) + { + // determine if coplanar + if (e->faces[0]->planenum == e->faces[1]->planenum) + e->coplanar = true; + } + } + } +} + +/* +================================================================= + + POINT TRIANGULATION + +================================================================= +*/ + +typedef struct triedge_s +{ + int p0, p1; + vec3_t normal; + vec_t dist; + struct triangle_s *tri; +} triedge_t; + +typedef struct triangle_s +{ + triedge_t *edges[3]; +} triangle_t; + +#define MAX_TRI_POINTS 1024 +#define MAX_TRI_EDGES (MAX_TRI_POINTS*6) +#define MAX_TRI_TRIS (MAX_TRI_POINTS*2) + +typedef struct +{ + int numpoints; + int numedges; + int numtris; + dplane_t *plane; + triedge_t *edgematrix[MAX_TRI_POINTS][MAX_TRI_POINTS]; + patch_t *points[MAX_TRI_POINTS]; + triedge_t edges[MAX_TRI_EDGES]; + triangle_t tris[MAX_TRI_TRIS]; +} triangulation_t; + +/* +=============== +AllocTriangulation +=============== +*/ +triangulation_t *AllocTriangulation (dplane_t *plane) +{ + triangulation_t *t; + + t = malloc(sizeof(triangulation_t)); + t->numpoints = 0; + t->numedges = 0; + t->numtris = 0; + + t->plane = plane; + +// memset (t->edgematrix, 0, sizeof(t->edgematrix)); + + return t; +} + +/* +=============== +FreeTriangulation +=============== +*/ +void FreeTriangulation (triangulation_t *tr) +{ + free (tr); +} + + +triedge_t *FindEdge (triangulation_t *trian, int p0, int p1) +{ + triedge_t *e, *be; + vec3_t v1; + vec3_t normal; + vec_t dist; + + if (trian->edgematrix[p0][p1]) + return trian->edgematrix[p0][p1]; + + if (trian->numedges > MAX_TRI_EDGES-2) + Error ("trian->numedges > MAX_TRI_EDGES-2"); + + VectorSubtract (trian->points[p1]->origin, trian->points[p0]->origin, v1); + VectorNormalize (v1, v1); + CrossProduct (v1, trian->plane->normal, normal); + dist = DotProduct (trian->points[p0]->origin, normal); + + e = &trian->edges[trian->numedges]; + e->p0 = p0; + e->p1 = p1; + e->tri = NULL; + VectorCopy (normal, e->normal); + e->dist = dist; + trian->numedges++; + trian->edgematrix[p0][p1] = e; + + be = &trian->edges[trian->numedges]; + be->p0 = p1; + be->p1 = p0; + be->tri = NULL; + VectorSubtract (vec3_origin, normal, be->normal); + be->dist = -dist; + trian->numedges++; + trian->edgematrix[p1][p0] = be; + + return e; +} + +triangle_t *AllocTriangle (triangulation_t *trian) +{ + triangle_t *t; + + if (trian->numtris >= MAX_TRI_TRIS) + Error ("trian->numtris >= MAX_TRI_TRIS"); + + t = &trian->tris[trian->numtris]; + trian->numtris++; + + return t; +} + +/* +============ +TriEdge_r +============ +*/ +void TriEdge_r (triangulation_t *trian, triedge_t *e) +{ + int i, bestp; + vec3_t v1, v2; + vec_t *p0, *p1, *p; + vec_t best, ang; + triangle_t *nt; + + if (e->tri) + return; // allready connected by someone + + // find the point with the best angle + p0 = trian->points[e->p0]->origin; + p1 = trian->points[e->p1]->origin; + best = 1.1; + for (i=0 ; i< trian->numpoints ; i++) + { + p = trian->points[i]->origin; + // a 0 dist will form a degenerate triangle + if (DotProduct(p, e->normal) - e->dist < 0) + continue; // behind edge + VectorSubtract (p0, p, v1); + VectorSubtract (p1, p, v2); + if (!VectorNormalize (v1,v1)) + continue; + if (!VectorNormalize (v2,v2)) + continue; + ang = DotProduct (v1, v2); + if (ang < best) + { + best = ang; + bestp = i; + } + } + if (best >= 1) + return; // edge doesn't match anything + + // make a new triangle + nt = AllocTriangle (trian); + nt->edges[0] = e; + nt->edges[1] = FindEdge (trian, e->p1, bestp); + nt->edges[2] = FindEdge (trian, bestp, e->p0); + for (i=0 ; i<3 ; i++) + nt->edges[i]->tri = nt; + TriEdge_r (trian, FindEdge (trian, bestp, e->p1)); + TriEdge_r (trian, FindEdge (trian, e->p0, bestp)); +} + +/* +============ +TriangulatePoints +============ +*/ +void TriangulatePoints (triangulation_t *trian) +{ + vec_t d, bestd; + vec3_t v1; + int bp1, bp2, i, j; + vec_t *p1, *p2; + triedge_t *e, *e2; + + if (trian->numpoints < 2) + return; + + // find the two closest points + bestd = 9999; + for (i=0 ; inumpoints ; i++) + { + p1 = trian->points[i]->origin; + for (j=i+1 ; jnumpoints ; j++) + { + p2 = trian->points[j]->origin; + VectorSubtract (p2, p1, v1); + d = VectorLength (v1); + if (d < bestd) + { + bestd = d; + bp1 = i; + bp2 = j; + } + } + } + + e = FindEdge (trian, bp1, bp2); + e2 = FindEdge (trian, bp2, bp1); + TriEdge_r (trian, e); + TriEdge_r (trian, e2); +} + +/* +=============== +AddPointToTriangulation +=============== +*/ +void AddPointToTriangulation (patch_t *patch, triangulation_t *trian) +{ + int pnum; + + pnum = trian->numpoints; + if (pnum == MAX_TRI_POINTS) + Error ("trian->numpoints == MAX_TRI_POINTS"); + trian->points[pnum] = patch; + trian->numpoints++; +} + +/* +=============== +LerpTriangle +=============== +*/ +void LerpTriangle (triangulation_t *trian, triangle_t *t, vec3_t point, vec3_t color) +{ + patch_t *p1, *p2, *p3; + vec3_t base, d1, d2; + float x, y, x1, y1, x2, y2; + + p1 = trian->points[t->edges[0]->p0]; + p2 = trian->points[t->edges[1]->p0]; + p3 = trian->points[t->edges[2]->p0]; + + VectorCopy (p1->totallight, base); + VectorSubtract (p2->totallight, base, d1); + VectorSubtract (p3->totallight, base, d2); + + x = DotProduct (point, t->edges[0]->normal) - t->edges[0]->dist; + y = DotProduct (point, t->edges[2]->normal) - t->edges[2]->dist; + + x1 = 0; + y1 = DotProduct (p2->origin, t->edges[2]->normal) - t->edges[2]->dist; + + x2 = DotProduct (p3->origin, t->edges[0]->normal) - t->edges[0]->dist; + y2 = 0; + + if (fabs(y1)edges[i]; + d = DotProduct (e->normal, point) - e->dist; + if (d < 0) + return false; // not inside + } + + return true; +} + +/* +=============== +SampleTriangulation +=============== +*/ +void SampleTriangulation (vec3_t point, triangulation_t *trian, vec3_t color) +{ + triangle_t *t; + triedge_t *e; + vec_t d, best; + patch_t *p0, *p1; + vec3_t v1, v2; + int i, j; + + if (trian->numpoints == 0) + { + VectorClear (color); + return; + } + if (trian->numpoints == 1) + { + VectorCopy (trian->points[0]->totallight, color); + return; + } + + // search for triangles + for (t = trian->tris, j=0 ; j < trian->numtris ; t++, j++) + { + if (!PointInTriangle (point, t)) + continue; + + // this is it + LerpTriangle (trian, t, point, color); + return; + } + + // search for exterior edge + for (e=trian->edges, j=0 ; j< trian->numedges ; e++, j++) + { + if (e->tri) + continue; // not an exterior edge + + d = DotProduct (point, e->normal) - e->dist; + if (d < 0) + continue; // not in front of edge + + p0 = trian->points[e->p0]; + p1 = trian->points[e->p1]; + + VectorSubtract (p1->origin, p0->origin, v1); + VectorNormalize (v1, v1); + VectorSubtract (point, p0->origin, v2); + d = DotProduct (v2, v1); + if (d < 0) + continue; + if (d > 1) + continue; + for (i=0 ; i<3 ; i++) + color[i] = p0->totallight[i] + d * (p1->totallight[i] - p0->totallight[i]); + return; + } + + // search for nearest point + best = 99999; + p1 = NULL; + for (j=0 ; jnumpoints ; j++) + { + p0 = trian->points[j]; + VectorSubtract (point, p0->origin, v1); + d = VectorLength (v1); + if (d < best) + { + best = d; + p1 = p0; + } + } + + if (!p1) + Error ("SampleTriangulation: no points"); + + VectorCopy (p1->totallight, color); +} + +/* +================================================================= + + LIGHTMAP SAMPLE GENERATION + +================================================================= +*/ + + +#define SINGLEMAP (64*64*4) + +typedef struct +{ + vec_t facedist; + vec3_t facenormal; + + int numsurfpt; + vec3_t surfpt[SINGLEMAP]; + + vec3_t modelorg; // for origined bmodels + + vec3_t texorg; + vec3_t worldtotex[2]; // s = (world - texorg) . worldtotex[0] + vec3_t textoworld[2]; // world = texorg + s * textoworld[0] + + vec_t exactmins[2], exactmaxs[2]; + + int texmins[2], texsize[2]; + int surfnum; + dface_t *face; +} lightinfo_t; + + +/* +================ +CalcFaceExtents + +Fills in s->texmins[] and s->texsize[] +also sets exactmins[] and exactmaxs[] +================ +*/ +void CalcFaceExtents (lightinfo_t *l) +{ + dface_t *s; + vec_t mins[2], maxs[2], val; + int i,j, e; + dvertex_t *v; + texinfo_t *tex; + vec3_t vt; + + s = l->face; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -99999; + + tex = &texinfo[s->texinfo]; + + for (i=0 ; inumedges ; i++) + { + e = dsurfedges[s->firstedge+i]; + if (e >= 0) + v = dvertexes + dedges[e].v[0]; + else + v = dvertexes + dedges[-e].v[1]; + +// VectorAdd (v->point, l->modelorg, vt); + VectorCopy (v->point, vt); + + for (j=0 ; j<2 ; j++) + { + val = DotProduct (vt, tex->vecs[j]) + tex->vecs[j][3]; + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + l->exactmins[i] = mins[i]; + l->exactmaxs[i] = maxs[i]; + + mins[i] = floor(mins[i]/16); + maxs[i] = ceil(maxs[i]/16); + + l->texmins[i] = mins[i]; + l->texsize[i] = maxs[i] - mins[i]; + if (l->texsize[0] * l->texsize[1] > SINGLEMAP/4) // div 4 for extrasamples + Error ("Surface to large to map"); + } +} + +/* +================ +CalcFaceVectors + +Fills in texorg, worldtotex. and textoworld +================ +*/ +void CalcFaceVectors (lightinfo_t *l) +{ + texinfo_t *tex; + int i, j; + vec3_t texnormal; + vec_t distscale; + vec_t dist, len; + int w, h; + + tex = &texinfo[l->face->texinfo]; + +// convert from float to double + for (i=0 ; i<2 ; i++) + for (j=0 ; j<3 ; j++) + l->worldtotex[i][j] = tex->vecs[i][j]; + +// calculate a normal to the texture axis. points can be moved along this +// without changing their S/T + texnormal[0] = tex->vecs[1][1]*tex->vecs[0][2] + - tex->vecs[1][2]*tex->vecs[0][1]; + texnormal[1] = tex->vecs[1][2]*tex->vecs[0][0] + - tex->vecs[1][0]*tex->vecs[0][2]; + texnormal[2] = tex->vecs[1][0]*tex->vecs[0][1] + - tex->vecs[1][1]*tex->vecs[0][0]; + VectorNormalize (texnormal, texnormal); + +// flip it towards plane normal + distscale = DotProduct (texnormal, l->facenormal); + if (!distscale) + { + qprintf ("WARNING: Texture axis perpendicular to face\n"); + distscale = 1; + } + if (distscale < 0) + { + distscale = -distscale; + VectorSubtract (vec3_origin, texnormal, texnormal); + } + +// distscale is the ratio of the distance along the texture normal to +// the distance along the plane normal + distscale = 1/distscale; + + for (i=0 ; i<2 ; i++) + { + len = VectorLength (l->worldtotex[i]); + dist = DotProduct (l->worldtotex[i], l->facenormal); + dist *= distscale; + VectorMA (l->worldtotex[i], -dist, texnormal, l->textoworld[i]); + VectorScale (l->textoworld[i], (1/len)*(1/len), l->textoworld[i]); + } + + +// calculate texorg on the texture plane + for (i=0 ; i<3 ; i++) + l->texorg[i] = -tex->vecs[0][3]* l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i]; + +// project back to the face plane + dist = DotProduct (l->texorg, l->facenormal) - l->facedist - 1; + dist *= distscale; + VectorMA (l->texorg, -dist, texnormal, l->texorg); + + // compensate for org'd bmodels + VectorAdd (l->texorg, l->modelorg, l->texorg); + + // total sample count + h = l->texsize[1]+1; + w = l->texsize[0]+1; + l->numsurfpt = w * h; +} + +/* +================= +CalcPoints + +For each texture aligned grid point, back project onto the plane +to get the world xyz value of the sample point +================= +*/ +void CalcPoints (lightinfo_t *l, float sofs, float tofs) +{ + int i; + int s, t, j; + int w, h, step; + vec_t starts, startt, us, ut; + vec_t *surf; + vec_t mids, midt; + vec3_t facemid; + dleaf_t *leaf; + + surf = l->surfpt[0]; + mids = (l->exactmaxs[0] + l->exactmins[0])/2; + midt = (l->exactmaxs[1] + l->exactmins[1])/2; + + for (j=0 ; j<3 ; j++) + facemid[j] = l->texorg[j] + l->textoworld[0][j]*mids + l->textoworld[1][j]*midt; + + h = l->texsize[1]+1; + w = l->texsize[0]+1; + l->numsurfpt = w * h; + + starts = l->texmins[0]*16; + startt = l->texmins[1]*16; + step = 16; + + + for (t=0 ; ttexorg[j] + l->textoworld[0][j]*us + + l->textoworld[1][j]*ut; + + leaf = PointInLeaf (surf); + if (leaf->contents != CONTENTS_SOLID) + { + if (!TestLine_r (0, facemid, surf)) + break; // got it + } + + // nudge it + if (i & 1) + { + if (us > mids) + { + us -= 8; + if (us < mids) + us = mids; + } + else + { + us += 8; + if (us > mids) + us = mids; + } + } + else + { + if (ut > midt) + { + ut -= 8; + if (ut < midt) + ut = midt; + } + else + { + ut += 8; + if (ut > midt) + ut = midt; + } + } + } + } + } + +} + + +//============================================================== + + + +#define MAX_STYLES 32 +typedef struct +{ + int numsamples; + float *origins; + int numstyles; + int stylenums[MAX_STYLES]; + float *samples[MAX_STYLES]; +} facelight_t; + +directlight_t *directlights[MAX_MAP_LEAFS]; +facelight_t facelight[MAX_MAP_FACES]; +int numdlights; + +/* +================== +FindTargetEntity +================== +*/ +entity_t *FindTargetEntity (char *target) +{ + int i; + char *n; + + for (i=0 ; itotallight[0] < DIRECT_LIGHT + && p->totallight[1] < DIRECT_LIGHT + && p->totallight[2] < DIRECT_LIGHT) + continue; + + numdlights++; + dl = malloc(sizeof(directlight_t)); + memset (dl, 0, sizeof(*dl)); + + VectorCopy (p->origin, dl->origin); + + leaf = PointInLeaf (dl->origin); + cluster = leaf->cluster; + dl->next = directlights[cluster]; + directlights[cluster] = dl; + + dl->type = emit_surface; + VectorCopy (p->plane->normal, dl->normal); + + dl->intensity = ColorNormalize (p->totallight, dl->color); + dl->intensity *= p->area * direct_scale; + VectorClear (p->totallight); // all sent now + } + + // + // entities + // + for (i=0 ; iorigin); + dl->style = FloatForKey (e, "_style"); + if (!dl->style) + dl->style = FloatForKey (e, "style"); + if (dl->style < 0 || dl->style >= MAX_LSTYLES) + dl->style = 0; + + leaf = PointInLeaf (dl->origin); + cluster = leaf->cluster; + + dl->next = directlights[cluster]; + directlights[cluster] = dl; + + intensity = FloatForKey (e, "light"); + if (!intensity) + intensity = FloatForKey (e, "_light"); + if (!intensity) + intensity = 300; + _color = ValueForKey (e, "_color"); + if (_color && _color[1]) + { + sscanf (_color, "%f %f %f", &dl->color[0],&dl->color[1],&dl->color[2]); + ColorNormalize (dl->color, dl->color); + } + else + dl->color[0] = dl->color[1] = dl->color[2] = 1.0; + dl->intensity = intensity*entity_scale; + dl->type = emit_point; + + target = ValueForKey (e, "target"); + + if (!strcmp (name, "light_spot") || target[0]) + { + dl->type = emit_spotlight; + dl->stopdot = FloatForKey (e, "_cone"); + if (!dl->stopdot) + dl->stopdot = 10; + dl->stopdot = cos(dl->stopdot/180*3.14159); + if (target[0]) + { // point towards target + e2 = FindTargetEntity (target); + if (!e2) + printf ("WARNING: light at (%i %i %i) has missing target\n", + (int)dl->origin[0], (int)dl->origin[1], (int)dl->origin[2]); + else + { + GetVectorForKey (e2, "origin", dest); + VectorSubtract (dest, dl->origin, dl->normal); + VectorNormalize (dl->normal, dl->normal); + } + } + else + { // point down angle + angle = FloatForKey (e, "angle"); + if (angle == ANGLE_UP) + { + dl->normal[0] = dl->normal[1] = 0; + dl->normal[2] = 1; + } + else if (angle == ANGLE_DOWN) + { + dl->normal[0] = dl->normal[1] = 0; + dl->normal[2] = -1; + } + else + { + dl->normal[2] = 0; + dl->normal[0] = cos (angle/180*3.14159); + dl->normal[1] = sin (angle/180*3.14159); + } + } + } + } + + qprintf ("%i direct lights\n", numdlights); +} + +/* +============= +GatherSampleLight + +Lightscale is the normalizer for multisampling +============= +*/ +void GatherSampleLight (vec3_t pos, vec3_t normal, + float **styletable, int offset, int mapsize, float lightscale) +{ + int i; + directlight_t *l; + byte pvs[(MAX_MAP_LEAFS+7)/8]; + vec3_t delta; + float dot, dot2; + float dist; + float scale; + float *dest; + + // get the PVS for the pos to limit the number of checks + if (!PvsForOrigin (pos, pvs)) + { + return; + } + + for (i = 0 ; inumclusters ; i++) + { + if ( ! (pvs[ i>>3] & (1<<(i&7))) ) + continue; + + for (l=directlights[i] ; l ; l=l->next) + { + VectorSubtract (l->origin, pos, delta); + dist = VectorNormalize (delta, delta); + dot = DotProduct (delta, normal); + if (dot <= 0.001) + continue; // behind sample surface + + switch (l->type) + { + case emit_point: + // linear falloff + scale = (l->intensity - dist) * dot; + break; + + case emit_surface: + dot2 = -DotProduct (delta, l->normal); + if (dot2 <= 0.001) + goto skipadd; // behind light surface + scale = (l->intensity / (dist*dist) ) * dot * dot2; + break; + + case emit_spotlight: + // linear falloff + dot2 = -DotProduct (delta, l->normal); + if (dot2 <= l->stopdot) + goto skipadd; // outside light cone + scale = (l->intensity - dist) * dot; + break; + default: + Error ("Bad l->type"); + } + + if (TestLine_r (0, pos, l->origin)) + continue; // occluded + + if (scale <= 0) + continue; + + // if this style doesn't have a table yet, allocate one + if (!styletable[l->style]) + { + styletable[l->style] = malloc (mapsize); + memset (styletable[l->style], 0, mapsize); + } + + dest = styletable[l->style] + offset; + // add some light to it + VectorMA (dest, scale*lightscale, l->color, dest); + +skipadd: ; + } + } + +} + +/* +============= +AddSampleToPatch + +Take the sample's collected light and +add it back into the apropriate patch +for the radiosity pass. + +The sample is added to all patches that might include +any part of it. They are counted and averaged, so it +doesn't generate extra light. +============= +*/ +void AddSampleToPatch (vec3_t pos, vec3_t color, int facenum) +{ + patch_t *patch; + vec3_t mins, maxs; + int i; + + if (numbounce == 0) + return; + if (color[0] + color[1] + color[2] < 3) + return; + + for (patch = face_patches[facenum] ; patch ; patch=patch->next) + { + // see if the point is in this patch (roughly) + WindingBounds (patch->winding, mins, maxs); + for (i=0 ; i<3 ; i++) + { + if (mins[i] > pos[i] + 16) + goto nextpatch; + if (maxs[i] < pos[i] - 16) + goto nextpatch; + } + + // add the sample to the patch + patch->samples++; + VectorAdd (patch->samplelight, color, patch->samplelight); +nextpatch:; + } + +} + + +/* +============= +BuildFacelights +============= +*/ +float sampleofs[5][2] = +{ {0,0}, {-0.25, -0.25}, {0.25, -0.25}, {0.25, 0.25}, {-0.25, 0.25} }; + + +void BuildFacelights (int facenum) +{ + dface_t *f; + lightinfo_t l[5]; + float *styletable[MAX_LSTYLES]; + int i, j; + float *spot; + patch_t *patch; + int numsamples; + int tablesize; + facelight_t *fl; + + f = &dfaces[facenum]; + + if ( texinfo[f->texinfo].flags & (SURF_WARP|SURF_SKY) ) + return; // non-lit texture + + memset (styletable,0, sizeof(styletable)); + + if (extrasamples) + numsamples = 5; + else + numsamples = 1; + for (i=0 ; iplanenum].normal, l[i].facenormal); + l[i].facedist = dplanes[f->planenum].dist; + if (f->side) + { + VectorSubtract (vec3_origin, l[i].facenormal, l[i].facenormal); + l[i].facedist = -l[i].facedist; + } + + // get the origin offset for rotating bmodels + VectorCopy (face_offset[facenum], l[i].modelorg); + + CalcFaceVectors (&l[i]); + CalcFaceExtents (&l[i]); + CalcPoints (&l[i], sampleofs[i][0], sampleofs[i][1]); + } + + tablesize = l[0].numsurfpt * sizeof(vec3_t); + styletable[0] = malloc(tablesize); + memset (styletable[0], 0, tablesize); + + fl = &facelight[facenum]; + fl->numsamples = l[0].numsurfpt; + fl->origins = malloc (tablesize); + memcpy (fl->origins, l[0].surfpt, tablesize); + + for (i=0 ; inext) + { + if (patch->samples) + { + VectorScale (patch->samplelight, 1.0/patch->samples, patch->samplelight); + } + else + { +// printf ("patch with no samples\n"); + } + } + + for (i=0 ; inumstyles == MAX_STYLES) + break; + fl->samples[fl->numstyles] = styletable[i]; + fl->stylenums[fl->numstyles] = i; + fl->numstyles++; + } + + // the light from DIRECT_LIGHTS is sent out, but the + // texture itself should still be full bright + + if (face_patches[facenum]->baselight[0] >= DIRECT_LIGHT || + face_patches[facenum]->baselight[1] >= DIRECT_LIGHT || + face_patches[facenum]->baselight[2] >= DIRECT_LIGHT + ) + { + spot = fl->samples[0]; + for (i=0 ; ibaselight, spot); + } + } +} + + +/* +============= +FinalLightFace + +Add the indirect lighting on top of the direct +lighting and save into final map format +============= +*/ +void FinalLightFace (int facenum) +{ + dface_t *f; + int i, j, k, st; + vec3_t lb; + patch_t *patch; + triangulation_t *trian; + facelight_t *fl; + float minlight; + float max, newmax; + byte *dest; + int pfacenum; + vec3_t facemins, facemaxs; + + f = &dfaces[facenum]; + fl = &facelight[facenum]; + + if ( texinfo[f->texinfo].flags & (SURF_WARP|SURF_SKY) ) + return; // non-lit texture + + ThreadLock (); + f->lightofs = lightdatasize; + lightdatasize += fl->numstyles*(fl->numsamples*3); + +// add green sentinals between lightmaps +#if 0 +lightdatasize += 64*3; +for (i=0 ; i<64 ; i++) +dlightdata[lightdatasize-(i+1)*3 + 1] = 255; +#endif + + if (lightdatasize > MAX_MAP_LIGHTING) + Error ("MAX_MAP_LIGHTING"); + ThreadUnlock (); + + f->styles[0] = 0; + f->styles[1] = f->styles[2] = f->styles[3] = 0xff; + + // + // set up the triangulation + // + if (numbounce > 0) + { + ClearBounds (facemins, facemaxs); + for (i=0 ; inumedges ; i++) + { + int ednum; + + ednum = dsurfedges[f->firstedge+i]; + if (ednum >= 0) + AddPointToBounds (dvertexes[dedges[ednum].v[0]].point, + facemins, facemaxs); + else + AddPointToBounds (dvertexes[dedges[-ednum].v[1]].point, + facemins, facemaxs); + } + + trian = AllocTriangulation (&dplanes[f->planenum]); + + // for all faces on the plane, add the nearby patches + // to the triangulation + for (pfacenum = planelinks[f->side][f->planenum] + ; pfacenum ; pfacenum = facelinks[pfacenum]) + { + for (patch = face_patches[pfacenum] ; patch ; patch=patch->next) + { + for (i=0 ; i < 3 ; i++) + { + if (facemins[i] - patch->origin[i] > subdiv*2) + break; + if (patch->origin[i] - facemaxs[i] > subdiv*2) + break; + } + if (i != 3) + continue; // not needed for this face + AddPointToTriangulation (patch, trian); + } + } + for (i=0 ; inumpoints ; i++) + memset (trian->edgematrix[i], 0, trian->numpoints*sizeof(trian->edgematrix[0][0]) ); + TriangulatePoints (trian); + } + + // + // sample the triangulation + // + + // _minlight allows models that have faces that would not be + // illuminated to receive a mottled light pattern instead of + // black + minlight = FloatForKey (face_entity[facenum], "_minlight") * 128; + + dest = &dlightdata[f->lightofs]; + + if (fl->numstyles > MAXLIGHTMAPS) + { + fl->numstyles = MAXLIGHTMAPS; + printf ("face with too many lightstyles: (%f %f %f)\n", + face_patches[facenum]->origin[0], + face_patches[facenum]->origin[1], + face_patches[facenum]->origin[2] + ); + } + + for (st=0 ; stnumstyles ; st++) + { + f->styles[st] = fl->stylenums[st]; + for (j=0 ; jnumsamples ; j++) + { + VectorCopy ( (fl->samples[st]+j*3), lb); + if (numbounce > 0 && st == 0) + { + vec3_t add; + + SampleTriangulation (fl->origins + j*3, trian, add); + VectorAdd (lb, add, lb); + } + // add an ambient term if desired + lb[0] += ambient; + lb[1] += ambient; + lb[2] += ambient; + + VectorScale (lb, lightscale, lb); + + // we need to clamp without allowing hue to change + for (k=0 ; k<3 ; k++) + if (lb[k] < 1) + lb[k] = 1; + max = lb[0]; + if (lb[1] > max) + max = lb[1]; + if (lb[2] > max) + max = lb[2]; + newmax = max; + if (newmax < 0) + newmax = 0; // roundoff problems + if (newmax < minlight) + { + newmax = minlight + (rand()%48); + } + if (newmax > maxlight) + newmax = maxlight; + + for (k=0 ; k<3 ; k++) + { + *dest++ = lb[k]*newmax/max; + } + } + } + + if (numbounce > 0) + FreeTriangulation (trian); +} diff --git a/tools/quake2/extra/bsp/qrad3/makefile b/tools/quake2/extra/bsp/qrad3/makefile new file mode 100644 index 00000000..4fb26c14 --- /dev/null +++ b/tools/quake2/extra/bsp/qrad3/makefile @@ -0,0 +1,77 @@ + +CFLAGS = -c +LDFLAGS = +ODIR = baddir + +EXEBASE = qrad3 +EXE = $(ODIR)/qrad3 +all: $(EXE) + +_next: + make "CFLAGS = -c -g -I../../common" "ODIR = next" + +_irix: + make "CFLAGS = -c -Ofast=ip32_10k -I../../common -Xcpluscomm" "LDFLAGS = -Ofast=ip32_10k" "ODIR = irix" + +_irixdebug: + make "CFLAGS = -c -g -I../../common -Xcpluscomm" "LDFLAGS = " "ODIR = irix" + +_irixinst: + make "CFLAGS = -c -Ofast=ip32_10k -I../../common -Xcpluscomm" "LDFLAGS = -Ofast=ip32_10k" "ODIR = irix" + cp irix/$(EXEBASE) /limbo/quake2/bin_irix + +_irixclean: + rm -f irix/*.o irix/$(EXEBASE) + +_osf: + make "CFLAGS = -c -O4 -I../../common -threads" "LDFLAGS = -threads" "ODIR = osf" + +clean: + rm -f irix/*.o irix/$(EXEBASE) + +install: + cp irix/$(EXEBASE) /limbo/quake2/bin_irix + + +FILES = $(ODIR)/bspfile.o $(ODIR)/cmdlib.o $(ODIR)/lbmlib.o $(ODIR)/mathlib.o $(ODIR)/scriplib.o $(ODIR)/polylib.o $(ODIR)/qrad3.o $(ODIR)/threads.o $(ODIR)/trace.o $(ODIR)/lightmap.o $(ODIR)/patches.o + +$(EXE) : $(FILES) + cc -o $(EXE) $(LDFLAGS) $(FILES) -lm + +$(ODIR)/qrad3.o : qrad3.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/patches.o : patches.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/trace.o : trace.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/vismat.o : vismat.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/lightmap.o : lightmap.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i + +$(ODIR)/cmdlib.o : ../../common/cmdlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/lbmlib.o : ../../common/lbmlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/mathlib.o : ../../common/mathlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/polylib.o : ../../common/polylib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/scriplib.o : ../../common/scriplib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/threads.o : ../../common/threads.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/bspfile.o : ../../common/bspfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i diff --git a/tools/quake2/extra/bsp/qrad3/patches.c b/tools/quake2/extra/bsp/qrad3/patches.c new file mode 100644 index 00000000..fbae0c32 --- /dev/null +++ b/tools/quake2/extra/bsp/qrad3/patches.c @@ -0,0 +1,515 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qrad.h" + +vec3_t texture_reflectivity[MAX_MAP_TEXINFO]; + +/* +=================================================================== + + TEXTURE LIGHT VALUES + +=================================================================== +*/ + +/* +====================== +CalcTextureReflectivity +====================== +*/ +void CalcTextureReflectivity (void) +{ + int i; + int j, k, texels; + int color[3]; + int texel; + byte *palette; + char path[1024]; + float r, scale; + miptex_t *mt; + + sprintf (path, "%spics/colormap.pcx", gamedir); + + // get the game palette + Load256Image (path, NULL, &palette, NULL, NULL); + + // allways set index 0 even if no textures + texture_reflectivity[0][0] = 0.5; + texture_reflectivity[0][1] = 0.5; + texture_reflectivity[0][2] = 0.5; + + for (i=0 ; iwidth)*LittleLong(mt->height); + color[0] = color[1] = color[2] = 0; + + for (j=0 ; joffsets[0]) + j]; + for (k=0 ; k<3 ; k++) + color[k] += palette[texel*3+k]; + } + + for (j=0 ; j<3 ; j++) + { + r = color[j]/texels/255.0; + texture_reflectivity[i][j] = r; + } + // scale the reflectivity up, because the textures are + // so dim + scale = ColorNormalize (texture_reflectivity[i], + texture_reflectivity[i]); + if (scale < 0.5) + { + scale *= 2; + VectorScale (texture_reflectivity[i], scale, texture_reflectivity[i]); + } +#if 0 +texture_reflectivity[i][0] = 0.5; +texture_reflectivity[i][1] = 0.5; +texture_reflectivity[i][2] = 0.5; +#endif + } +} + +/* +======================================================================= + +MAKE FACES + +======================================================================= +*/ + +/* +============= +WindingFromFace +============= +*/ +winding_t *WindingFromFace (dface_t *f) +{ + int i; + int se; + dvertex_t *dv; + int v; + winding_t *w; + + w = AllocWinding (f->numedges); + w->numpoints = f->numedges; + + for (i=0 ; inumedges ; i++) + { + se = dsurfedges[f->firstedge + i]; + if (se < 0) + v = dedges[-se].v[1]; + else + v = dedges[se].v[0]; + + dv = &dvertexes[v]; + VectorCopy (dv->point, w->p[i]); + } + + RemoveColinearPoints (w); + + return w; +} + +/* +============= +BaseLightForFace +============= +*/ +void BaseLightForFace (dface_t *f, vec3_t color) +{ + texinfo_t *tx; + + // + // check for light emited by texture + // + tx = &texinfo[f->texinfo]; + if (!(tx->flags & SURF_LIGHT) || tx->value == 0) + { + VectorClear (color); + return; + } + + VectorScale (texture_reflectivity[f->texinfo], tx->value, color); +} + +qboolean IsSky (dface_t *f) +{ + texinfo_t *tx; + + tx = &texinfo[f->texinfo]; + if (tx->flags & SURF_SKY) + return true; + return false; +} + +/* +============= +MakePatchForFace +============= +*/ +float totalarea; +void MakePatchForFace (int fn, winding_t *w) +{ + dface_t *f; + float area; + patch_t *patch; + dplane_t *pl; + int i; + vec3_t color; + dleaf_t *leaf; + + f = &dfaces[fn]; + + area = WindingArea (w); + totalarea += area; + + patch = &patches[num_patches]; + if (num_patches == MAX_PATCHES) + Error ("num_patches == MAX_PATCHES"); + patch->next = face_patches[fn]; + face_patches[fn] = patch; + + patch->winding = w; + + if (f->side) + patch->plane = &backplanes[f->planenum]; + else + patch->plane = &dplanes[f->planenum]; + if (face_offset[fn][0] || face_offset[fn][1] || face_offset[fn][2] ) + { // origin offset faces must create new planes + if (numplanes + fakeplanes >= MAX_MAP_PLANES) + Error ("numplanes + fakeplanes >= MAX_MAP_PLANES"); + pl = &dplanes[numplanes + fakeplanes]; + fakeplanes++; + + *pl = *(patch->plane); + pl->dist += DotProduct (face_offset[fn], pl->normal); + patch->plane = pl; + } + + WindingCenter (w, patch->origin); + VectorAdd (patch->origin, patch->plane->normal, patch->origin); + leaf = PointInLeaf(patch->origin); + patch->cluster = leaf->cluster; + if (patch->cluster == -1) + qprintf ("patch->cluster == -1\n"); + + patch->area = area; + if (patch->area <= 1) + patch->area = 1; + patch->sky = IsSky (f); + + VectorCopy (texture_reflectivity[f->texinfo], patch->reflectivity); + + // non-bmodel patches can emit light + if (fn < dmodels[0].numfaces) + { + BaseLightForFace (f, patch->baselight); + + ColorNormalize (patch->reflectivity, color); + + for (i=0 ; i<3 ; i++) + patch->baselight[i] *= color[i]; + + VectorCopy (patch->baselight, patch->totallight); + } + num_patches++; +} + + +entity_t *EntityForModel (int modnum) +{ + int i; + char *s; + char name[16]; + + sprintf (name, "*%i", modnum); + // search the entities for one using modnum + for (i=0 ; inumfaces ; j++) + { + fn = mod->firstface + j; + face_entity[fn] = ent; + VectorCopy (origin, face_offset[fn]); + f = &dfaces[fn]; + w = WindingFromFace (f); + for (k=0 ; knumpoints ; k++) + { + VectorAdd (w->p[k], origin, w->p[k]); + } + MakePatchForFace (fn, w); + } + } + + qprintf ("%i sqaure feet\n", (int)(totalarea/64)); +} + +/* +======================================================================= + +SUBDIVIDE + +======================================================================= +*/ + +void FinishSplit (patch_t *patch, patch_t *newp) +{ + dleaf_t *leaf; + + VectorCopy (patch->baselight, newp->baselight); + VectorCopy (patch->totallight, newp->totallight); + VectorCopy (patch->reflectivity, newp->reflectivity); + newp->plane = patch->plane; + newp->sky = patch->sky; + + patch->area = WindingArea (patch->winding); + newp->area = WindingArea (newp->winding); + + if (patch->area <= 1) + patch->area = 1; + if (newp->area <= 1) + newp->area = 1; + + WindingCenter (patch->winding, patch->origin); + VectorAdd (patch->origin, patch->plane->normal, patch->origin); + leaf = PointInLeaf(patch->origin); + patch->cluster = leaf->cluster; + if (patch->cluster == -1) + qprintf ("patch->cluster == -1\n"); + + WindingCenter (newp->winding, newp->origin); + VectorAdd (newp->origin, newp->plane->normal, newp->origin); + leaf = PointInLeaf(newp->origin); + newp->cluster = leaf->cluster; + if (newp->cluster == -1) + qprintf ("patch->cluster == -1\n"); +} + +/* +============= +SubdividePatch + +Chops the patch only if its local bounds exceed the max size +============= +*/ +void SubdividePatch (patch_t *patch) +{ + winding_t *w, *o1, *o2; + vec3_t mins, maxs, total; + vec3_t split; + vec_t dist; + int i, j; + vec_t v; + patch_t *newp; + + w = patch->winding; + mins[0] = mins[1] = mins[2] = 99999; + maxs[0] = maxs[1] = maxs[2] = -99999; + for (i=0 ; inumpoints ; i++) + { + for (j=0 ; j<3 ; j++) + { + v = w->p[i][j]; + if (v < mins[j]) + mins[j] = v; + if (v > maxs[j]) + maxs[j] = v; + } + } + VectorSubtract (maxs, mins, total); + for (i=0 ; i<3 ; i++) + if (total[i] > (subdiv+1) ) + break; + if (i == 3) + { + // no splitting needed + return; + } + + // + // split the winding + // + VectorCopy (vec3_origin, split); + split[i] = 1; + dist = (mins[i] + maxs[i])*0.5; + ClipWindingEpsilon (w, split, dist, ON_EPSILON, &o1, &o2); + + // + // create a new patch + // + if (num_patches == MAX_PATCHES) + Error ("MAX_PATCHES"); + newp = &patches[num_patches]; + num_patches++; + + newp->next = patch->next; + patch->next = newp; + + patch->winding = o1; + newp->winding = o2; + + FinishSplit (patch, newp); + + SubdividePatch (patch); + SubdividePatch (newp); +} + + +/* +============= +DicePatch + +Chops the patch by a global grid +============= +*/ +void DicePatch (patch_t *patch) +{ + winding_t *w, *o1, *o2; + vec3_t mins, maxs; + vec3_t split; + vec_t dist; + int i; + patch_t *newp; + + w = patch->winding; + WindingBounds (w, mins, maxs); + for (i=0 ; i<3 ; i++) + if (floor((mins[i]+1)/subdiv) < floor((maxs[i]-1)/subdiv)) + break; + if (i == 3) + { + // no splitting needed + return; + } + + // + // split the winding + // + VectorCopy (vec3_origin, split); + split[i] = 1; + dist = subdiv*(1+floor((mins[i]+1)/subdiv)); + ClipWindingEpsilon (w, split, dist, ON_EPSILON, &o1, &o2); + + // + // create a new patch + // + if (num_patches == MAX_PATCHES) + Error ("MAX_PATCHES"); + newp = &patches[num_patches]; + num_patches++; + + newp->next = patch->next; + patch->next = newp; + + patch->winding = o1; + newp->winding = o2; + + FinishSplit (patch, newp); + + DicePatch (patch); + DicePatch (newp); +} + + +/* +============= +SubdividePatches +============= +*/ +void SubdividePatches (void) +{ + int i, num; + + if (subdiv < 1) + return; + + num = num_patches; // because the list will grow + for (i=0 ; i +#endif + +typedef enum +{ + emit_surface, + emit_point, + emit_spotlight +} emittype_t; + + + +typedef struct directlight_s +{ + struct directlight_s *next; + emittype_t type; + + float intensity; + int style; + vec3_t origin; + vec3_t color; + vec3_t normal; // for surfaces and spotlights + float stopdot; // for spotlights +} directlight_t; + + +// the sum of all tranfer->transfer values for a given patch +// should equal exactly 0x10000, showing that all radiance +// reaches other patches +typedef struct +{ + unsigned short patch; + unsigned short transfer; +} transfer_t; + + +#define MAX_PATCHES 65000 // larger will cause 32 bit overflows + +typedef struct patch_s +{ + winding_t *winding; + struct patch_s *next; // next in face + int numtransfers; + transfer_t *transfers; + + int cluster; // for pvs checking + vec3_t origin; + dplane_t *plane; + + qboolean sky; + + vec3_t totallight; // accumulated by radiosity + // does NOT include light + // accounted for by direct lighting + float area; + + // illuminance * reflectivity = radiosity + vec3_t reflectivity; + vec3_t baselight; // emissivity only + + // each style 0 lightmap sample in the patch will be + // added up to get the average illuminance of the entire patch + vec3_t samplelight; + int samples; // for averaging direct light +} patch_t; + +extern patch_t *face_patches[MAX_MAP_FACES]; +extern entity_t *face_entity[MAX_MAP_FACES]; +extern vec3_t face_offset[MAX_MAP_FACES]; // for rotating bmodels +extern patch_t patches[MAX_PATCHES]; +extern unsigned num_patches; + +extern int leafparents[MAX_MAP_LEAFS]; +extern int nodeparents[MAX_MAP_NODES]; + +extern float lightscale; + + +void MakeShadowSplits (void); + +//============================================== + + +void BuildVisMatrix (void); +qboolean CheckVisBit (unsigned p1, unsigned p2); + +//============================================== + +extern float ambient, maxlight; + +void LinkPlaneFaces (void); + +extern qboolean extrasamples; +extern int numbounce; + +extern directlight_t *directlights[MAX_MAP_LEAFS]; + +extern byte nodehit[MAX_MAP_NODES]; + +void BuildLightmaps (void); + +void BuildFacelights (int facenum); + +void FinalLightFace (int facenum); + +qboolean PvsForOrigin (vec3_t org, byte *pvs); + +int TestLine_r (int node, vec3_t start, vec3_t stop); + +void CreateDirectLights (void); + +dleaf_t *PointInLeaf (vec3_t point); + + +extern dplane_t backplanes[MAX_MAP_PLANES]; +extern int fakeplanes; // created planes for origin offset + +extern float subdiv; + +extern float direct_scale; +extern float entity_scale; + +int PointInLeafnum (vec3_t point); +void MakeTnodes (dmodel_t *bm); +void MakePatches (void); +void SubdividePatches (void); +void PairEdges (void); +void CalcTextureReflectivity (void); diff --git a/tools/quake2/extra/bsp/qrad3/qrad3.c b/tools/quake2/extra/bsp/qrad3/qrad3.c new file mode 100644 index 00000000..9c7caddc --- /dev/null +++ b/tools/quake2/extra/bsp/qrad3/qrad3.c @@ -0,0 +1,717 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qrad.h" + + + +/* + +NOTES +----- + +every surface must be divided into at least two patches each axis + +*/ + +patch_t *face_patches[MAX_MAP_FACES]; +entity_t *face_entity[MAX_MAP_FACES]; +patch_t patches[MAX_PATCHES]; +unsigned num_patches; + +vec3_t radiosity[MAX_PATCHES]; // light leaving a patch +vec3_t illumination[MAX_PATCHES]; // light arriving at a patch + +vec3_t face_offset[MAX_MAP_FACES]; // for rotating bmodels +dplane_t backplanes[MAX_MAP_PLANES]; + +char inbase[32], outbase[32]; + +int fakeplanes; // created planes for origin offset + +int numbounce = 8; +qboolean extrasamples; + +float subdiv = 64; +qboolean dumppatches; + +void BuildLightmaps (void); +int TestLine (vec3_t start, vec3_t stop); + +int junk; + +float ambient = 0; +float maxlight = 196; + +float lightscale = 1.0; + +qboolean glview; + +qboolean nopvs; + +char source[1024]; + +float direct_scale = 0.4; +float entity_scale = 1.0; + +/* +=================================================================== + +MISC + +=================================================================== +*/ + + +/* +============= +MakeBackplanes +============= +*/ +void MakeBackplanes (void) +{ + int i; + + for (i=0 ; ichildren[i]; + if (j < 0) + leafparents[-j - 1] = nodenum; + else + MakeParents (j, nodenum); + } +} + + +/* +=================================================================== + +TRANSFER SCALES + +=================================================================== +*/ + +int PointInLeafnum (vec3_t point) +{ + int nodenum; + vec_t dist; + dnode_t *node; + dplane_t *plane; + + nodenum = 0; + while (nodenum >= 0) + { + node = &dnodes[nodenum]; + plane = &dplanes[node->planenum]; + dist = DotProduct (point, plane->normal) - plane->dist; + if (dist > 0) + nodenum = node->children[0]; + else + nodenum = node->children[1]; + } + + return -nodenum - 1; +} + + +dleaf_t *PointInLeaf (vec3_t point) +{ + int num; + + num = PointInLeafnum (point); + return &dleafs[num]; +} + + +qboolean PvsForOrigin (vec3_t org, byte *pvs) +{ + dleaf_t *leaf; + + if (!visdatasize) + { + memset (pvs, 255, (numleafs+7)/8 ); + return true; + } + + leaf = PointInLeaf (org); + if (leaf->cluster == -1) + return false; // in solid leaf + + DecompressVis (dvisdata + dvis->bitofs[leaf->cluster][DVIS_PVS], pvs); + return true; +} + + +/* +============= +MakeTransfers + +============= +*/ +int total_transfer; + +void MakeTransfers (int i) +{ + int j; + vec3_t delta; + vec_t dist, scale; + float trans; + int itrans; + patch_t *patch, *patch2; + float total; + dplane_t plane; + vec3_t origin; + float transfers[MAX_PATCHES], *all_transfers; + int s; + int itotal; + byte pvs[(MAX_MAP_LEAFS+7)/8]; + int cluster; + + patch = patches + i; + total = 0; + + VectorCopy (patch->origin, origin); + plane = *patch->plane; + + if (!PvsForOrigin (patch->origin, pvs)) + return; + + // find out which patch2s will collect light + // from patch + + all_transfers = transfers; + patch->numtransfers = 0; + for (j=0, patch2 = patches ; jcluster; + if (cluster == -1) + continue; + if ( ! ( pvs[cluster>>3] & (1<<(cluster&7)) ) ) + continue; // not in pvs + } + + // calculate vector + VectorSubtract (patch2->origin, origin, delta); + dist = VectorNormalize (delta, delta); + if (!dist) + continue; // should never happen + + // reletive angles + scale = DotProduct (delta, plane.normal); + scale *= -DotProduct (delta, patch2->plane->normal); + if (scale <= 0) + continue; + + // check exact tramsfer + if (TestLine_r (0, patch->origin, patch2->origin) ) + continue; + + trans = scale * patch2->area / (dist*dist); + + if (trans < 0) + trans = 0; // rounding errors... + + transfers[j] = trans; + if (trans > 0) + { + total += trans; + patch->numtransfers++; + } + } + + // copy the transfers out and normalize + // total should be somewhere near PI if everything went right + // because partial occlusion isn't accounted for, and nearby + // patches have underestimated form factors, it will usually + // be higher than PI + if (patch->numtransfers) + { + transfer_t *t; + + if (patch->numtransfers < 0 || patch->numtransfers > MAX_PATCHES) + Error ("Weird numtransfers"); + s = patch->numtransfers * sizeof(transfer_t); + patch->transfers = malloc (s); + if (!patch->transfers) + Error ("Memory allocation failure"); + + // + // normalize all transfers so all of the light + // is transfered to the surroundings + // + t = patch->transfers; + itotal = 0; + for (j=0 ; jtransfer = itrans; + t->patch = j; + t++; + } + } + + // don't bother locking around this. not that important. + total_transfer += patch->numtransfers; +} + + +/* +============= +FreeTransfers +============= +*/ +void FreeTransfers (void) +{ + int i; + + for (i=0 ; iwinding; + fprintf (out, "%i\n", w->numpoints); + for (i=0 ; inumpoints ; i++) + { + fprintf (out, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", + w->p[i][0], + w->p[i][1], + w->p[i][2], + patch->totallight[0], + patch->totallight[1], + patch->totallight[2]); + } + fprintf (out, "\n"); + } + + fclose (out); +} + +/* +============= +WriteGlView +============= +*/ +void WriteGlView (void) +{ + char name[1024]; + FILE *f; + int i, j; + patch_t *p; + winding_t *w; + + strcpy (name, source); + StripExtension (name); + strcat (name, ".glr"); + + f = fopen (name, "w"); + if (!f) + Error ("Couldn't open %s", f); + + for (j=0 ; jwinding; + fprintf (f, "%i\n", w->numpoints); + for (i=0 ; inumpoints ; i++) + { + fprintf (f, "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n", + w->p[i][0], + w->p[i][1], + w->p[i][2], + p->totallight[0]/128, + p->totallight[1]/128, + p->totallight[2]/128); + } + fprintf (f, "\n"); + } + + fclose (f); +} + + +//============================================================== + +/* +============= +CollectLight +============= +*/ +float CollectLight (void) +{ + int i, j; + patch_t *patch; + vec_t total; + + total = 0; + + for (i=0, patch=patches ; isky) + { + VectorClear (radiosity[i]); + VectorClear (illumination[i]); + continue; + } + + for (j=0 ; j<3 ; j++) + { + patch->totallight[j] += illumination[i][j] / patch->area; + radiosity[i][j] = illumination[i][j] * patch->reflectivity[j]; + } + + total += radiosity[i][0] + radiosity[i][1] + radiosity[i][2]; + VectorClear (illumination[i]); + } + + return total; +} + + +/* +============= +ShootLight + +Send light out to other patches + Run multi-threaded +============= +*/ +void ShootLight (int patchnum) +{ + int k, l; + transfer_t *trans; + int num; + patch_t *patch; + vec3_t send; + + // this is the amount of light we are distributing + // prescale it so that multiplying by the 16 bit + // transfer values gives a proper output value + for (k=0 ; k<3 ; k++) + send[k] = radiosity[patchnum][k] / 0x10000; + patch = &patches[patchnum]; + + trans = patch->transfers; + num = patch->numtransfers; + + for (k=0 ; kpatch][l] += send[l]*trans->transfer; + } +} + +/* +============= +BounceLight +============= +*/ +void BounceLight (void) +{ + int i, j; + float added; + char name[64]; + patch_t *p; + + for (i=0 ; itotallight[j] = p->samplelight[j]; + radiosity[i][j] = p->samplelight[j] * p->reflectivity[j] * p->area; + } + } + + for (i=0 ; itotallight[0] < 0 || patch->totallight[1] < 0 || patch->totallight[2] < 0) + Error ("negative patch totallight\n"); + } +} + +/* +============= +RadWorld +============= +*/ +void RadWorld (void) +{ + if (numnodes == 0 || numfaces == 0) + Error ("Empty map"); + MakeBackplanes (); + MakeParents (0, -1); + MakeTnodes (&dmodels[0]); + + // turn each face into a single patch + MakePatches (); + + // subdivide patches to a maximum dimension + SubdividePatches (); + + // create directlights out of patches and lights + CreateDirectLights (); + + // build initial facelights + RunThreadsOnIndividual (numfaces, true, BuildFacelights); + + if (numbounce > 0) + { + // build transfer lists + RunThreadsOnIndividual (num_patches, true, MakeTransfers); + qprintf ("transfer lists: %5.1f megs\n" + , (float)total_transfer * sizeof(transfer_t) / (1024*1024)); + + // spread light around + BounceLight (); + + FreeTransfers (); + + CheckPatches (); + } + + if (glview) + WriteGlView (); + + // blend bounced light into direct light and save + PairEdges (); + LinkPlaneFaces (); + + lightdatasize = 0; + RunThreadsOnIndividual (numfaces, true, FinalLightFace); +} + + +/* +======== +main + +light modelfile +======== +*/ +int main (int argc, char **argv) +{ + int i; + double start, end; + char name[1024]; + + printf ("----- Radiosity ----\n"); + + verbose = false; + + for (i=1 ; i 255) + maxlight = 255; + + if (i != argc - 1) + Error ("usage: qrad [-v] [-chop num] [-scale num] [-ambient num] [-maxlight num] [-threads num] bspfile"); + + start = I_FloatTime (); + + SetQdirFromPath (argv[i]); + strcpy (source, ExpandArg(argv[i])); + StripExtension (source); + DefaultExtension (source, ".bsp"); + +// ReadLightFile (); + + sprintf (name, "%s%s", inbase, source); + printf ("reading %s\n", name); + LoadBSPFile (name); + ParseEntities (); + CalcTextureReflectivity (); + + if (!visdatasize) + { + printf ("No vis information, direct lighting only.\n"); + numbounce = 0; + ambient = 0.1; + } + + RadWorld (); + + sprintf (name, "%s%s", outbase, source); + printf ("writing %s\n", name); + WriteBSPFile (name); + + end = I_FloatTime (); + printf ("%5.0f seconds elapsed\n", end-start); + + return 0; +} + diff --git a/tools/quake2/extra/bsp/qrad3/trace.c b/tools/quake2/extra/bsp/qrad3/trace.c new file mode 100644 index 00000000..bb5f4949 --- /dev/null +++ b/tools/quake2/extra/bsp/qrad3/trace.c @@ -0,0 +1,295 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "cmdlib.h" +#include "mathlib.h" +#include "bspfile.h" + +#define ON_EPSILON 0.1 + +typedef struct tnode_s +{ + int type; + vec3_t normal; + float dist; + int children[2]; + int pad; +} tnode_t; + +tnode_t *tnodes, *tnode_p; + +/* +============== +MakeTnode + +Converts the disk node structure into the efficient tracing structure +============== +*/ +void MakeTnode (int nodenum) +{ + tnode_t *t; + dplane_t *plane; + int i; + dnode_t *node; + + t = tnode_p++; + + node = dnodes + nodenum; + plane = dplanes + node->planenum; + + t->type = plane->type; + VectorCopy (plane->normal, t->normal); + t->dist = plane->dist; + + for (i=0 ; i<2 ; i++) + { + if (node->children[i] < 0) + t->children[i] = (dleafs[-node->children[i] - 1].contents & CONTENTS_SOLID) | (1<<31); + else + { + t->children[i] = tnode_p - tnodes; + MakeTnode (node->children[i]); + } + } + +} + + +/* +============= +MakeTnodes + +Loads the node structure out of a .bsp file to be used for light occlusion +============= +*/ +void MakeTnodes (dmodel_t *bm) +{ + // 32 byte align the structs + tnodes = malloc( (numnodes+1) * sizeof(tnode_t)); + tnodes = (tnode_t *)(((int)tnodes + 31)&~31); + tnode_p = tnodes; + + MakeTnode (0); +} + + +//========================================================== + + +int TestLine_r (int node, vec3_t start, vec3_t stop) +{ + tnode_t *tnode; + float front, back; + vec3_t mid; + float frac; + int side; + int r; + + if (node & (1<<31)) + return node & ~(1<<31); // leaf node + + tnode = &tnodes[node]; + switch (tnode->type) + { + case PLANE_X: + front = start[0] - tnode->dist; + back = stop[0] - tnode->dist; + break; + case PLANE_Y: + front = start[1] - tnode->dist; + back = stop[1] - tnode->dist; + break; + case PLANE_Z: + front = start[2] - tnode->dist; + back = stop[2] - tnode->dist; + break; + default: + front = (start[0]*tnode->normal[0] + start[1]*tnode->normal[1] + start[2]*tnode->normal[2]) - tnode->dist; + back = (stop[0]*tnode->normal[0] + stop[1]*tnode->normal[1] + stop[2]*tnode->normal[2]) - tnode->dist; + break; + } + + if (front >= -ON_EPSILON && back >= -ON_EPSILON) + return TestLine_r (tnode->children[0], start, stop); + + if (front < ON_EPSILON && back < ON_EPSILON) + return TestLine_r (tnode->children[1], start, stop); + + side = front < 0; + + frac = front / (front-back); + + mid[0] = start[0] + (stop[0] - start[0])*frac; + mid[1] = start[1] + (stop[1] - start[1])*frac; + mid[2] = start[2] + (stop[2] - start[2])*frac; + + r = TestLine_r (tnode->children[side], start, mid); + if (r) + return r; + return TestLine_r (tnode->children[!side], mid, stop); +} + +int TestLine (vec3_t start, vec3_t stop) +{ + return TestLine_r (0, start, stop); +} + +/* +============================================================================== + +LINE TRACING + +The major lighting operation is a point to point visibility test, performed +by recursive subdivision of the line by the BSP tree. + +============================================================================== +*/ + +typedef struct +{ + vec3_t backpt; + int side; + int node; +} tracestack_t; + + +/* +============== +TestLine +============== +*/ +qboolean _TestLine (vec3_t start, vec3_t stop) +{ + int node; + float front, back; + tracestack_t *tstack_p; + int side; + float frontx,fronty, frontz, backx, backy, backz; + tracestack_t tracestack[64]; + tnode_t *tnode; + + frontx = start[0]; + fronty = start[1]; + frontz = start[2]; + backx = stop[0]; + backy = stop[1]; + backz = stop[2]; + + tstack_p = tracestack; + node = 0; + + while (1) + { + if (node == CONTENTS_SOLID) + { +#if 0 + float d1, d2, d3; + + d1 = backx - frontx; + d2 = backy - fronty; + d3 = backz - frontz; + + if (d1*d1 + d2*d2 + d3*d3 > 1) +#endif + return false; // DONE! + } + + while (node < 0) + { + // pop up the stack for a back side + tstack_p--; + if (tstack_p < tracestack) + return true; + node = tstack_p->node; + + // set the hit point for this plane + + frontx = backx; + fronty = backy; + frontz = backz; + + // go down the back side + + backx = tstack_p->backpt[0]; + backy = tstack_p->backpt[1]; + backz = tstack_p->backpt[2]; + + node = tnodes[tstack_p->node].children[!tstack_p->side]; + } + + tnode = &tnodes[node]; + + switch (tnode->type) + { + case PLANE_X: + front = frontx - tnode->dist; + back = backx - tnode->dist; + break; + case PLANE_Y: + front = fronty - tnode->dist; + back = backy - tnode->dist; + break; + case PLANE_Z: + front = frontz - tnode->dist; + back = backz - tnode->dist; + break; + default: + front = (frontx*tnode->normal[0] + fronty*tnode->normal[1] + frontz*tnode->normal[2]) - tnode->dist; + back = (backx*tnode->normal[0] + backy*tnode->normal[1] + backz*tnode->normal[2]) - tnode->dist; + break; + } + + if (front > -ON_EPSILON && back > -ON_EPSILON) +// if (front > 0 && back > 0) + { + node = tnode->children[0]; + continue; + } + + if (front < ON_EPSILON && back < ON_EPSILON) +// if (front <= 0 && back <= 0) + { + node = tnode->children[1]; + continue; + } + + side = front < 0; + + front = front / (front-back); + + tstack_p->node = node; + tstack_p->side = side; + tstack_p->backpt[0] = backx; + tstack_p->backpt[1] = backy; + tstack_p->backpt[2] = backz; + + tstack_p++; + + backx = frontx + front*(backx-frontx); + backy = fronty + front*(backy-fronty); + backz = frontz + front*(backz-frontz); + + node = tnode->children[side]; + } +} + + diff --git a/tools/quake2/extra/bsp/qvis3/flow.c b/tools/quake2/extra/bsp/qvis3/flow.c new file mode 100644 index 00000000..66af998e --- /dev/null +++ b/tools/quake2/extra/bsp/qvis3/flow.c @@ -0,0 +1,788 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +#include "vis.h" + +/* + + each portal will have a list of all possible to see from first portal + + if (!thread->portalmightsee[portalnum]) + + portal mightsee + + for p2 = all other portals in leaf + get sperating planes + for all portals that might be seen by p2 + mark as unseen if not present in seperating plane + flood fill a new mightsee + save as passagemightsee + + + void CalcMightSee (leaf_t *leaf, +*/ + +int CountBits (byte *bits, int numbits) +{ + int i; + int c; + + c = 0; + for (i=0 ; i>3] & (1<<(i&7)) ) + c++; + + return c; +} + +int c_fullskip; +int c_portalskip, c_leafskip; +int c_vistest, c_mighttest; + +int c_chop, c_nochop; + +int active; + +void CheckStack (leaf_t *leaf, threaddata_t *thread) +{ + pstack_t *p, *p2; + + for (p=thread->pstack_head.next ; p ; p=p->next) + { +// printf ("="); + if (p->leaf == leaf) + Error ("CheckStack: leaf recursion"); + for (p2=thread->pstack_head.next ; p2 != p ; p2=p2->next) + if (p2->leaf == p->leaf) + Error ("CheckStack: late leaf recursion"); + } +// printf ("\n"); +} + + +winding_t *AllocStackWinding (pstack_t *stack) +{ + int i; + + for (i=0 ; i<3 ; i++) + { + if (stack->freewindings[i]) + { + stack->freewindings[i] = 0; + return &stack->windings[i]; + } + } + + Error ("AllocStackWinding: failed"); + + return NULL; +} + +void FreeStackWinding (winding_t *w, pstack_t *stack) +{ + int i; + + i = w - stack->windings; + + if (i<0 || i>2) + return; // not from local + + if (stack->freewindings[i]) + Error ("FreeStackWinding: allready free"); + stack->freewindings[i] = 1; +} + +/* +============== +ChopWinding + +============== +*/ +winding_t *ChopWinding (winding_t *in, pstack_t *stack, plane_t *split) +{ + vec_t dists[128]; + int sides[128]; + int counts[3]; + vec_t dot; + int i, j; + vec_t *p1, *p2; + vec3_t mid; + winding_t *neww; + + counts[0] = counts[1] = counts[2] = 0; + +// determine sides for each point + for (i=0 ; inumpoints ; i++) + { + dot = DotProduct (in->points[i], split->normal); + dot -= split->dist; + dists[i] = dot; + if (dot > ON_EPSILON) + sides[i] = SIDE_FRONT; + else if (dot < -ON_EPSILON) + sides[i] = SIDE_BACK; + else + { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + + if (!counts[1]) + return in; // completely on front side + + if (!counts[0]) + { + FreeStackWinding (in, stack); + return NULL; + } + + sides[i] = sides[0]; + dists[i] = dists[0]; + + neww = AllocStackWinding (stack); + + neww->numpoints = 0; + + for (i=0 ; inumpoints ; i++) + { + p1 = in->points[i]; + + if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING) + { + FreeStackWinding (neww, stack); + return in; // can't chop -- fall back to original + } + + if (sides[i] == SIDE_ON) + { + VectorCopy (p1, neww->points[neww->numpoints]); + neww->numpoints++; + continue; + } + + if (sides[i] == SIDE_FRONT) + { + VectorCopy (p1, neww->points[neww->numpoints]); + neww->numpoints++; + } + + if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING) + { + FreeStackWinding (neww, stack); + return in; // can't chop -- fall back to original + } + + // generate a split point + p2 = in->points[(i+1)%in->numpoints]; + + dot = dists[i] / (dists[i]-dists[i+1]); + for (j=0 ; j<3 ; j++) + { // avoid round off error when possible + if (split->normal[j] == 1) + mid[j] = split->dist; + else if (split->normal[j] == -1) + mid[j] = -split->dist; + else + mid[j] = p1[j] + dot*(p2[j]-p1[j]); + } + + VectorCopy (mid, neww->points[neww->numpoints]); + neww->numpoints++; + } + +// free the original winding + FreeStackWinding (in, stack); + + return neww; +} + + +/* +============== +ClipToSeperators + +Source, pass, and target are an ordering of portals. + +Generates seperating planes canidates by taking two points from source and one +point from pass, and clips target by them. + +If target is totally clipped away, that portal can not be seen through. + +Normal clip keeps target on the same side as pass, which is correct if the +order goes source, pass, target. If the order goes pass, source, target then +flipclip should be set. +============== +*/ +winding_t *ClipToSeperators (winding_t *source, winding_t *pass, winding_t *target, qboolean flipclip, pstack_t *stack) +{ + int i, j, k, l; + plane_t plane; + vec3_t v1, v2; + float d; + vec_t length; + int counts[3]; + qboolean fliptest; + +// check all combinations + for (i=0 ; inumpoints ; i++) + { + l = (i+1)%source->numpoints; + VectorSubtract (source->points[l] , source->points[i], v1); + + // fing a vertex of pass that makes a plane that puts all of the + // vertexes of pass on the front side and all of the vertexes of + // source on the back side + for (j=0 ; jnumpoints ; j++) + { + VectorSubtract (pass->points[j], source->points[i], v2); + + plane.normal[0] = v1[1]*v2[2] - v1[2]*v2[1]; + plane.normal[1] = v1[2]*v2[0] - v1[0]*v2[2]; + plane.normal[2] = v1[0]*v2[1] - v1[1]*v2[0]; + + // if points don't make a valid plane, skip it + + length = plane.normal[0] * plane.normal[0] + + plane.normal[1] * plane.normal[1] + + plane.normal[2] * plane.normal[2]; + + if (length < ON_EPSILON) + continue; + + length = 1/sqrt(length); + + plane.normal[0] *= length; + plane.normal[1] *= length; + plane.normal[2] *= length; + + plane.dist = DotProduct (pass->points[j], plane.normal); + + // + // find out which side of the generated seperating plane has the + // source portal + // +#if 1 + fliptest = false; + for (k=0 ; knumpoints ; k++) + { + if (k == i || k == l) + continue; + d = DotProduct (source->points[k], plane.normal) - plane.dist; + if (d < -ON_EPSILON) + { // source is on the negative side, so we want all + // pass and target on the positive side + fliptest = false; + break; + } + else if (d > ON_EPSILON) + { // source is on the positive side, so we want all + // pass and target on the negative side + fliptest = true; + break; + } + } + if (k == source->numpoints) + continue; // planar with source portal +#else + fliptest = flipclip; +#endif + // + // flip the normal if the source portal is backwards + // + if (fliptest) + { + VectorSubtract (vec3_origin, plane.normal, plane.normal); + plane.dist = -plane.dist; + } +#if 1 + // + // if all of the pass portal points are now on the positive side, + // this is the seperating plane + // + counts[0] = counts[1] = counts[2] = 0; + for (k=0 ; knumpoints ; k++) + { + if (k==j) + continue; + d = DotProduct (pass->points[k], plane.normal) - plane.dist; + if (d < -ON_EPSILON) + break; + else if (d > ON_EPSILON) + counts[0]++; + else + counts[2]++; + } + if (k != pass->numpoints) + continue; // points on negative side, not a seperating plane + + if (!counts[0]) + continue; // planar with seperating plane +#else + k = (j+1)%pass->numpoints; + d = DotProduct (pass->points[k], plane.normal) - plane.dist; + if (d < -ON_EPSILON) + continue; + k = (j+pass->numpoints-1)%pass->numpoints; + d = DotProduct (pass->points[k], plane.normal) - plane.dist; + if (d < -ON_EPSILON) + continue; +#endif + // + // flip the normal if we want the back side + // + if (flipclip) + { + VectorSubtract (vec3_origin, plane.normal, plane.normal); + plane.dist = -plane.dist; + } + + // + // clip target by the seperating plane + // + target = ChopWinding (target, stack, &plane); + if (!target) + return NULL; // target is not visible + } + } + + return target; +} + + + +/* +================== +RecursiveLeafFlow + +Flood fill through the leafs +If src_portal is NULL, this is the originating leaf +================== +*/ +void RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack) +{ + pstack_t stack; + portal_t *p; + plane_t backplane; + leaf_t *leaf; + int i, j; + long *test, *might, *vis, more; + int pnum; + + thread->c_chains++; + + leaf = &leafs[leafnum]; +// CheckStack (leaf, thread); + + prevstack->next = &stack; + + stack.next = NULL; + stack.leaf = leaf; + stack.portal = NULL; + + might = (long *)stack.mightsee; + vis = (long *)thread->base->portalvis; + +// check all portals for flowing into other leafs + for (i=0 ; inumportals ; i++) + { + p = leaf->portals[i]; + pnum = p - portals; + + if ( ! (prevstack->mightsee[pnum >> 3] & (1<<(pnum&7)) ) ) + { + continue; // can't possibly see it + } + + // if the portal can't see anything we haven't allready seen, skip it + if (p->status == stat_done) + { + test = (long *)p->portalvis; + } + else + { + test = (long *)p->portalflood; + } + + more = 0; + for (j=0 ; jmightsee)[j] & test[j]; + more |= (might[j] & ~vis[j]); + } + + if (!more && + (thread->base->portalvis[pnum>>3] & (1<<(pnum&7))) ) + { // can't see anything new + continue; + } + + // get plane of portal, point normal into the neighbor leaf + stack.portalplane = p->plane; + VectorSubtract (vec3_origin, p->plane.normal, backplane.normal); + backplane.dist = -p->plane.dist; + +// c_portalcheck++; + + stack.portal = p; + stack.next = NULL; + stack.freewindings[0] = 1; + stack.freewindings[1] = 1; + stack.freewindings[2] = 1; + +#if 1 +{ +float d; + + d = DotProduct (p->origin, thread->pstack_head.portalplane.normal); + d -= thread->pstack_head.portalplane.dist; + if (d < -p->radius) + { + continue; + } + else if (d > p->radius) + { + stack.pass = p->winding; + } + else + { + stack.pass = ChopWinding (p->winding, &stack, &thread->pstack_head.portalplane); + if (!stack.pass) + continue; + } +} +#else + stack.pass = ChopWinding (p->winding, &stack, &thread->pstack_head.portalplane); + if (!stack.pass) + continue; +#endif + + +#if 1 +{ +float d; + + d = DotProduct (thread->base->origin, p->plane.normal); + d -= p->plane.dist; + if (d > p->radius) + { + continue; + } + else if (d < -p->radius) + { + stack.source = prevstack->source; + } + else + { + stack.source = ChopWinding (prevstack->source, &stack, &backplane); + if (!stack.source) + continue; + } +} +#else + stack.source = ChopWinding (prevstack->source, &stack, &backplane); + if (!stack.source) + continue; +#endif + + if (!prevstack->pass) + { // the second leaf can only be blocked if coplanar + + // mark the portal as visible + thread->base->portalvis[pnum>>3] |= (1<<(pnum&7)); + + RecursiveLeafFlow (p->leaf, thread, &stack); + continue; + } + + stack.pass = ClipToSeperators (stack.source, prevstack->pass, stack.pass, false, &stack); + if (!stack.pass) + continue; + + stack.pass = ClipToSeperators (prevstack->pass, stack.source, stack.pass, true, &stack); + if (!stack.pass) + continue; + + // mark the portal as visible + thread->base->portalvis[pnum>>3] |= (1<<(pnum&7)); + + // flow through it for real + RecursiveLeafFlow (p->leaf, thread, &stack); + } +} + + +/* +=============== +PortalFlow + +generates the portalvis bit vector +=============== +*/ +void PortalFlow (int portalnum) +{ + threaddata_t data; + int i; + portal_t *p; + int c_might, c_can; + + p = sorted_portals[portalnum]; + p->status = stat_working; + + c_might = CountBits (p->portalflood, numportals*2); + + memset (&data, 0, sizeof(data)); + data.base = p; + + data.pstack_head.portal = p; + data.pstack_head.source = p->winding; + data.pstack_head.portalplane = p->plane; + for (i=0 ; iportalflood)[i]; + RecursiveLeafFlow (p->leaf, &data, &data.pstack_head); + + p->status = stat_done; + + c_can = CountBits (p->portalvis, numportals*2); + + qprintf ("portal:%4i mightsee:%4i cansee:%4i (%i chains)\n", + (int)(p - portals), c_might, c_can, data.c_chains); +} + + +/* +=============================================================================== + +This is a rough first-order aproximation that is used to trivially reject some +of the final calculations. + + +Calculates portalfront and portalflood bit vectors + +thinking about: + +typedef struct passage_s +{ + struct passage_s *next; + struct portal_s *to; + stryct sep_s *seperators; + byte *mightsee; +} passage_t; + +typedef struct portal_s +{ + struct passage_s *passages; + int leaf; // leaf portal faces into +} portal_s; + +leaf = portal->leaf +clear +for all portals + + +calc portal visibility + clear bit vector + for all passages + passage visibility + + +for a portal to be visible to a passage, it must be on the front of +all seperating planes, and both portals must be behind the mew portal + +=============================================================================== +*/ + +int c_flood, c_vis; + + +/* +================== +SimpleFlood + +================== +*/ +void SimpleFlood (portal_t *srcportal, int leafnum) +{ + int i; + leaf_t *leaf; + portal_t *p; + int pnum; + + leaf = &leafs[leafnum]; + + for (i=0 ; inumportals ; i++) + { + p = leaf->portals[i]; + pnum = p - portals; + if ( ! (srcportal->portalfront[pnum>>3] & (1<<(pnum&7)) ) ) + continue; + + if (srcportal->portalflood[pnum>>3] & (1<<(pnum&7)) ) + continue; + + srcportal->portalflood[pnum>>3] |= (1<<(pnum&7)); + + SimpleFlood (srcportal, p->leaf); + } +} + +/* +============== +BasePortalVis +============== +*/ +void BasePortalVis (int portalnum) +{ + int j, k; + portal_t *tp, *p; + float d; + winding_t *w; + + p = portals+portalnum; + + p->portalfront = malloc (portalbytes); + memset (p->portalfront, 0, portalbytes); + + p->portalflood = malloc (portalbytes); + memset (p->portalflood, 0, portalbytes); + + p->portalvis = malloc (portalbytes); + memset (p->portalvis, 0, portalbytes); + + for (j=0, tp = portals ; jwinding; + for (k=0 ; knumpoints ; k++) + { + d = DotProduct (w->points[k], p->plane.normal) + - p->plane.dist; + if (d > ON_EPSILON) + break; + } + if (k == w->numpoints) + continue; // no points on front + + w = p->winding; + for (k=0 ; knumpoints ; k++) + { + d = DotProduct (w->points[k], tp->plane.normal) + - tp->plane.dist; + if (d < -ON_EPSILON) + break; + } + if (k == w->numpoints) + continue; // no points on front + + p->portalfront[j>>3] |= (1<<(j&7)); + } + + SimpleFlood (p, p->leaf); + + p->nummightsee = CountBits (p->portalflood, numportals*2); +// printf ("portal %i: %i mightsee\n", portalnum, p->nummightsee); + c_flood += p->nummightsee; +} + + + + + +/* +=============================================================================== + +This is a second order aproximation + +Calculates portalvis bit vector + +WAAAAAAY too slow. + +=============================================================================== +*/ + +/* +================== +RecursiveLeafBitFlow + +================== +*/ +void RecursiveLeafBitFlow (int leafnum, byte *mightsee, byte *cansee) +{ + portal_t *p; + leaf_t *leaf; + int i, j; + long more; + int pnum; + byte newmight[MAX_PORTALS/8]; + + leaf = &leafs[leafnum]; + +// check all portals for flowing into other leafs + for (i=0 ; inumportals ; i++) + { + p = leaf->portals[i]; + pnum = p - portals; + + // if some previous portal can't see it, skip + if (! (mightsee[pnum>>3] & (1<<(pnum&7)) ) ) + continue; + + // if this portal can see some portals we mightsee, recurse + more = 0; + for (j=0 ; jportalflood)[j]; + more |= ((long *)newmight)[j] & ~((long *)cansee)[j]; + } + + if (!more) + continue; // can't see anything new + + cansee[pnum>>3] |= (1<<(pnum&7)); + + RecursiveLeafBitFlow (p->leaf, newmight, cansee); + } +} + +/* +============== +BetterPortalVis +============== +*/ +void BetterPortalVis (int portalnum) +{ + portal_t *p; + + p = portals+portalnum; + + RecursiveLeafBitFlow (p->leaf, p->portalflood, p->portalvis); + + // build leaf vis information + p->nummightsee = CountBits (p->portalvis, numportals*2); + c_vis += p->nummightsee; +} + + diff --git a/tools/quake2/extra/bsp/qvis3/makefile b/tools/quake2/extra/bsp/qvis3/makefile new file mode 100644 index 00000000..57946de1 --- /dev/null +++ b/tools/quake2/extra/bsp/qvis3/makefile @@ -0,0 +1,62 @@ + +CFLAGS = -c +LDFLAGS = +ODIR = baddir + +EXEBASE = qvis3 +EXE = $(ODIR)/qvis3 +all: $(EXE) + +_next: + make "CFLAGS = -c -g -I../../common" "ODIR = next" + +_irix: + make "CFLAGS = -c -Ofast=ip32_10k -I../../common -Xcpluscomm" "LDFLAGS = -Ofast=ip32_10k" "ODIR = irix" + +_irixinst: + make "CFLAGS = -c -Ofast=ip32_10k -I../../common -Xcpluscomm" "LDFLAGS = -Ofast=ip32_10k" "ODIR = irix" + cp irix/$(EXEBASE) /limbo/quake2/bin_irix + +_irixclean: + rm -f irix/*.o irix/$(EXEBASE) + +_osf: + make "CFLAGS = -c -O4 -I../../common -threads" "LDFLAGS = -threads -lm" "ODIR = osf" + +clean: + rm -f irix/*.o irix/$(EXEBASE) + +install: + cp irix/$(EXEBASE) /limbo/quake2/bin_irix + + +FILES = $(ODIR)/bspfile.o $(ODIR)/cmdlib.o $(ODIR)/mathlib.o $(ODIR)/scriplib.o $(ODIR)/threads.o $(ODIR)/qvis3.o $(ODIR)/flow.o + +$(EXE) : $(FILES) + cc -o $(EXE) $(LDFLAGS) $(FILES) + +$(ODIR)/qvis3.o : qvis3.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/flow.o : flow.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i + +$(ODIR)/cmdlib.o : ../../common/cmdlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/mathlib.o : ../../common/mathlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/polylib.o : ../../common/polylib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/scriplib.o : ../../common/scriplib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/threads.o : ../../common/threads.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/bspfile.o : ../../common/bspfile.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i diff --git a/tools/quake2/extra/bsp/qvis3/qvis3.c b/tools/quake2/extra/bsp/qvis3/qvis3.c new file mode 100644 index 00000000..7cc87510 --- /dev/null +++ b/tools/quake2/extra/bsp/qvis3/qvis3.c @@ -0,0 +1,615 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "vis.h" +#include "threads.h" +#include "stdlib.h" + +int numportals; +int portalclusters; + +char inbase[32]; +char outbase[32]; + +portal_t *portals; +leaf_t *leafs; + +int c_portaltest, c_portalpass, c_portalcheck; + +byte *uncompressedvis; + +byte *vismap, *vismap_p, *vismap_end; // past visfile +int originalvismapsize; + +int leafbytes; // (portalclusters+63)>>3 +int leaflongs; + +int portalbytes, portallongs; + +qboolean fastvis; +qboolean nosort; + +int testlevel = 2; + +int totalvis; + +portal_t *sorted_portals[MAX_MAP_PORTALS*2]; + + +//============================================================================= + +void PlaneFromWinding (winding_t *w, plane_t *plane) +{ + vec3_t v1, v2; + +// calc plane + VectorSubtract (w->points[2], w->points[1], v1); + VectorSubtract (w->points[0], w->points[1], v2); + CrossProduct (v2, v1, plane->normal); + VectorNormalize (plane->normal, plane->normal); + plane->dist = DotProduct (w->points[0], plane->normal); +} + + +/* +================== +NewWinding +================== +*/ +winding_t *NewWinding (int points) +{ + winding_t *w; + int size; + + if (points > MAX_POINTS_ON_WINDING) + Error ("NewWinding: %i points", points); + + size = (int)((winding_t *)0)->points[points]; + w = malloc (size); + memset (w, 0, size); + + return w; +} + + + +void pw(winding_t *w) +{ + int i; + for (i=0 ; inumpoints ; i++) + printf ("(%5.1f, %5.1f, %5.1f)\n",w->points[i][0], w->points[i][1],w->points[i][2]); +} + +void prl(leaf_t *l) +{ + int i; + portal_t *p; + plane_t pl; + + for (i=0 ; inumportals ; i++) + { + p = l->portals[i]; + pl = p->plane; + printf ("portal %4i to leaf %4i : %7.1f : (%4.1f, %4.1f, %4.1f)\n",(int)(p-portals),p->leaf,pl.dist, pl.normal[0], pl.normal[1], pl.normal[2]); + } +} + + +//============================================================================= + +/* +============= +SortPortals + +Sorts the portals from the least complex, so the later ones can reuse +the earlier information. +============= +*/ +int PComp (const void *a, const void *b) +{ + if ( (*(portal_t **)a)->nummightsee == (*(portal_t **)b)->nummightsee) + return 0; + if ( (*(portal_t **)a)->nummightsee < (*(portal_t **)b)->nummightsee) + return -1; + return 1; +} +void SortPortals (void) +{ + int i; + + for (i=0 ; i>3] & (1<<(i&7)) ) + { + p = portals+i; + leafbits[p->leaf>>3] |= (1<<(p->leaf&7)); + } + } + + c_leafs = CountBits (leafbits, portalclusters); + + return c_leafs; +} + + +/* +=============== +ClusterMerge + +Merges the portal visibility for a leaf +=============== +*/ +void ClusterMerge (int leafnum) +{ + leaf_t *leaf; + byte portalvector[MAX_PORTALS/8]; + byte uncompressed[MAX_MAP_LEAFS/8]; + byte compressed[MAX_MAP_LEAFS/8]; + int i, j; + int numvis; + byte *dest; + portal_t *p; + int pnum; + + // OR together all the portalvis bits + + memset (portalvector, 0, portalbytes); + leaf = &leafs[leafnum]; + for (i=0 ; inumportals ; i++) + { + p = leaf->portals[i]; + if (p->status != stat_done) + Error ("portal not done"); + for (j=0 ; jportalvis)[j]; + pnum = p - portals; + portalvector[pnum>>3] |= 1<<(pnum&7); + } + + // convert portal bits to leaf bits + numvis = LeafVectorFromPortalVector (portalvector, uncompressed); + + if (uncompressed[leafnum>>3] & (1<<(leafnum&7))) + printf ("WARNING: Leaf portals saw into leaf\n"); + + uncompressed[leafnum>>3] |= (1<<(leafnum&7)); + numvis++; // count the leaf itself + + // save uncompressed for PHS calculation + memcpy (uncompressedvis + leafnum*leafbytes, uncompressed, leafbytes); + +// +// compress the bit string +// + qprintf ("cluster %4i : %4i visible\n", leafnum, numvis); + totalvis += numvis; + + i = CompressVis (uncompressed, compressed); + + dest = vismap_p; + vismap_p += i; + + if (vismap_p > vismap_end) + Error ("Vismap expansion overflow"); + + dvis->bitofs[leafnum][DVIS_PVS] = dest-vismap; + + memcpy (dest, compressed, i); +} + + +/* +================== +CalcPortalVis +================== +*/ +void CalcPortalVis (void) +{ + int i; + +// fastvis just uses mightsee for a very loose bound + if (fastvis) + { + for (i=0 ; iwinding; + VectorCopy (vec3_origin, total); + for (i=0 ; inumpoints ; i++) + { + VectorAdd (total, w->points[i], total); + } + + for (i=0 ; i<3 ; i++) + total[i] /= w->numpoints; + + bestr = 0; + for (i=0 ; inumpoints ; i++) + { + VectorSubtract (w->points[i], total, dist); + r = VectorLength (dist); + if (r > bestr) + bestr = r; + } + VectorCopy (total, p->origin); + p->radius = bestr; +} + +/* +============ +LoadPortals +============ +*/ +void LoadPortals (char *name) +{ + int i, j; + portal_t *p; + leaf_t *l; + char magic[80]; + FILE *f; + int numpoints; + winding_t *w; + int leafnums[2]; + plane_t plane; + + if (!strcmp(name,"-")) + f = stdin; + else + { + f = fopen(name, "r"); + if (!f) + Error ("LoadPortals: couldn't read %s\n",name); + } + + if (fscanf (f,"%79s\n%i\n%i\n",magic, &portalclusters, &numportals) != 3) + Error ("LoadPortals: failed to read header"); + if (strcmp(magic,PORTALFILE)) + Error ("LoadPortals: not a portal file"); + + printf ("%4i portalclusters\n", portalclusters); + printf ("%4i numportals\n", numportals); + + // these counts should take advantage of 64 bit systems automatically + leafbytes = ((portalclusters+63)&~63)>>3; + leaflongs = leafbytes/sizeof(long); + + portalbytes = ((numportals*2+63)&~63)>>3; + portallongs = portalbytes/sizeof(long); + +// each file portal is split into two memory portals + portals = malloc(2*numportals*sizeof(portal_t)); + memset (portals, 0, 2*numportals*sizeof(portal_t)); + + leafs = malloc(portalclusters*sizeof(leaf_t)); + memset (leafs, 0, portalclusters*sizeof(leaf_t)); + + originalvismapsize = portalclusters*leafbytes; + uncompressedvis = malloc(originalvismapsize); + + vismap = vismap_p = dvisdata; + dvis->numclusters = portalclusters; + vismap_p = (byte *)&dvis->bitofs[portalclusters]; + + vismap_end = vismap + MAX_MAP_VISIBILITY; + + for (i=0, p=portals ; i MAX_POINTS_ON_WINDING) + Error ("LoadPortals: portal %i has too many points", i); + if ( (unsigned)leafnums[0] > portalclusters + || (unsigned)leafnums[1] > portalclusters) + Error ("LoadPortals: reading portal %i", i); + + w = p->winding = NewWinding (numpoints); + w->original = true; + w->numpoints = numpoints; + + for (j=0 ; jpoints[j][k] = v[k]; + } + fscanf (f, "\n"); + + // calc plane + PlaneFromWinding (w, &plane); + + // create forward portal + l = &leafs[leafnums[0]]; + if (l->numportals == MAX_PORTALS_ON_LEAF) + Error ("Leaf with too many portals"); + l->portals[l->numportals] = p; + l->numportals++; + + p->winding = w; + VectorSubtract (vec3_origin, plane.normal, p->plane.normal); + p->plane.dist = -plane.dist; + p->leaf = leafnums[1]; + SetPortalSphere (p); + p++; + + // create backwards portal + l = &leafs[leafnums[1]]; + if (l->numportals == MAX_PORTALS_ON_LEAF) + Error ("Leaf with too many portals"); + l->portals[l->numportals] = p; + l->numportals++; + + p->winding = NewWinding(w->numpoints); + p->winding->numpoints = w->numpoints; + for (j=0 ; jnumpoints ; j++) + { + VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]); + } + + p->plane = plane; + p->leaf = leafnums[0]; + SetPortalSphere (p); + p++; + + } + + fclose (f); +} + + +/* +================ +CalcPHS + +Calculate the PHS (Potentially Hearable Set) +by ORing together all the PVS visible from a leaf +================ +*/ +void CalcPHS (void) +{ + int i, j, k, l, index; + int bitbyte; + long *dest, *src; + byte *scan; + int count; + byte uncompressed[MAX_MAP_LEAFS/8]; + byte compressed[MAX_MAP_LEAFS/8]; + + printf ("Building PHS...\n"); + + count = 0; + for (i=0 ; i= portalclusters) + Error ("Bad bit in PVS"); // pad bits should be 0 + src = (long *)(uncompressedvis + index*leafbytes); + dest = (long *)uncompressed; + for (l=0 ; l>3] & (1<<(j&7)) ) + count++; + + // + // compress the bit string + // + j = CompressVis (uncompressed, compressed); + + dest = (long *)vismap_p; + vismap_p += j; + + if (vismap_p > vismap_end) + Error ("Vismap expansion overflow"); + + dvis->bitofs[i][DVIS_PHS] = (byte *)dest-vismap; + + memcpy (dest, compressed, j); + } + + printf ("Average clusters hearable: %i\n", count/portalclusters); +} + +/* +=========== +main +=========== +*/ +int main (int argc, char **argv) +{ + char portalfile[1024]; + char source[1024]; + char name[1024]; + int i; + double start, end; + + printf ("---- vis ----\n"); + + verbose = false; + for (i=1 ; i>3; + visrow = (dvis->numclusters + 7)>>3; + + for (j=0 ; j>3; + row = (dvis->numclusters+7)>>3; + out = decompressed; + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + if (!c) + Error ("DecompressVis: 0 repeat"); + in += 2; + while (c) + { + *out++ = 0; + c--; + } + } while (out - decompressed < row); +} + +//============================================================================= + +/* +============= +SwapBSPFile + +Byte swaps all data in a bsp file. +============= +*/ +void SwapBSPFile (qboolean todisk) +{ + int i, j; + dmodel_t *d; + + +// models + for (i=0 ; ifirstface = LittleLong (d->firstface); + d->numfaces = LittleLong (d->numfaces); + d->headnode = LittleLong (d->headnode); + + for (j=0 ; j<3 ; j++) + { + d->mins[j] = LittleFloat(d->mins[j]); + d->maxs[j] = LittleFloat(d->maxs[j]); + d->origin[j] = LittleFloat(d->origin[j]); + } + } + +// +// vertexes +// + for (i=0 ; inumclusters; + else + j = LittleLong(dvis->numclusters); + dvis->numclusters = LittleLong (dvis->numclusters); + for (i=0 ; ibitofs[i][0] = LittleLong (dvis->bitofs[i][0]); + dvis->bitofs[i][1] = LittleLong (dvis->bitofs[i][1]); + } +} + + +dheader_t *header; + +int CopyLump (int lump, void *dest, int size) +{ + int length, ofs; + + length = header->lumps[lump].filelen; + ofs = header->lumps[lump].fileofs; + + if (length % size) + Error ("LoadBSPFile: odd lump size"); + + memcpy (dest, (byte *)header + ofs, length); + + return length / size; +} + +/* +============= +LoadBSPFile +============= +*/ +void LoadBSPFile (char *filename) +{ + int i; + +// +// load the file header +// + LoadFile (filename, (void **)&header); + +// swap the header + for (i=0 ; i< sizeof(dheader_t)/4 ; i++) + ((int *)header)[i] = LittleLong ( ((int *)header)[i]); + + if (header->ident != IDBSPHEADER) + Error ("%s is not a IBSP file", filename); + if (header->version != BSPVERSION) + Error ("%s is version %i, not %i", filename, header->version, BSPVERSION); + + nummodels = CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t)); + numvertexes = CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t)); + numplanes = CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t)); + numleafs = CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t)); + numnodes = CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t)); + numtexinfo = CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t)); + numfaces = CopyLump (LUMP_FACES, dfaces, sizeof(dface_t)); + numleaffaces = CopyLump (LUMP_LEAFFACES, dleaffaces, sizeof(dleaffaces[0])); + numleafbrushes = CopyLump (LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0])); + numsurfedges = CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0])); + numedges = CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t)); + numbrushes = CopyLump (LUMP_BRUSHES, dbrushes, sizeof(dbrush_t)); + numbrushsides = CopyLump (LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t)); + numareas = CopyLump (LUMP_AREAS, dareas, sizeof(darea_t)); + numareaportals = CopyLump (LUMP_AREAPORTALS, dareaportals, sizeof(dareaportal_t)); + + visdatasize = CopyLump (LUMP_VISIBILITY, dvisdata, 1); + lightdatasize = CopyLump (LUMP_LIGHTING, dlightdata, 1); + entdatasize = CopyLump (LUMP_ENTITIES, dentdata, 1); + + CopyLump (LUMP_POP, dpop, 1); + + free (header); // everything has been copied out + +// +// swap everything +// + SwapBSPFile (false); +} + + +/* +============= +LoadBSPFileTexinfo + +Only loads the texinfo lump, so qdata can scan for textures +============= +*/ +void LoadBSPFileTexinfo (char *filename) +{ + int i; + FILE *f; + int length, ofs; + + header = malloc(sizeof(dheader_t)); + + f = fopen (filename, "rb"); + fread (header, sizeof(dheader_t), 1, f); + +// swap the header + for (i=0 ; i< sizeof(dheader_t)/4 ; i++) + ((int *)header)[i] = LittleLong ( ((int *)header)[i]); + + if (header->ident != IDBSPHEADER) + Error ("%s is not a IBSP file", filename); + if (header->version != BSPVERSION) + Error ("%s is version %i, not %i", filename, header->version, BSPVERSION); + + + length = header->lumps[LUMP_TEXINFO].filelen; + ofs = header->lumps[LUMP_TEXINFO].fileofs; + + fseek (f, ofs, SEEK_SET); + fread (texinfo, length, 1, f); + fclose (f); + + numtexinfo = length / sizeof(texinfo_t); + + free (header); // everything has been copied out + + SwapBSPFile (false); +} + + +//============================================================================ + +FILE *wadfile; +dheader_t outheader; + +void AddLump (int lumpnum, void *data, int len) +{ + lump_t *lump; + + lump = &header->lumps[lumpnum]; + + lump->fileofs = LittleLong( ftell(wadfile) ); + lump->filelen = LittleLong(len); + SafeWrite (wadfile, data, (len+3)&~3); +} + +/* +============= +WriteBSPFile + +Swaps the bsp file in place, so it should not be referenced again +============= +*/ +void WriteBSPFile (char *filename) +{ + header = &outheader; + memset (header, 0, sizeof(dheader_t)); + + SwapBSPFile (true); + + header->ident = LittleLong (IDBSPHEADER); + header->version = LittleLong (BSPVERSION); + + wadfile = SafeOpenWrite (filename); + SafeWrite (wadfile, header, sizeof(dheader_t)); // overwritten later + + AddLump (LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t)); + AddLump (LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t)); + AddLump (LUMP_VERTEXES, dvertexes, numvertexes*sizeof(dvertex_t)); + AddLump (LUMP_NODES, dnodes, numnodes*sizeof(dnode_t)); + AddLump (LUMP_TEXINFO, texinfo, numtexinfo*sizeof(texinfo_t)); + AddLump (LUMP_FACES, dfaces, numfaces*sizeof(dface_t)); + AddLump (LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t)); + AddLump (LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t)); + AddLump (LUMP_LEAFFACES, dleaffaces, numleaffaces*sizeof(dleaffaces[0])); + AddLump (LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0])); + AddLump (LUMP_SURFEDGES, dsurfedges, numsurfedges*sizeof(dsurfedges[0])); + AddLump (LUMP_EDGES, dedges, numedges*sizeof(dedge_t)); + AddLump (LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t)); + AddLump (LUMP_AREAS, dareas, numareas*sizeof(darea_t)); + AddLump (LUMP_AREAPORTALS, dareaportals, numareaportals*sizeof(dareaportal_t)); + + AddLump (LUMP_LIGHTING, dlightdata, lightdatasize); + AddLump (LUMP_VISIBILITY, dvisdata, visdatasize); + AddLump (LUMP_ENTITIES, dentdata, entdatasize); + AddLump (LUMP_POP, dpop, sizeof(dpop)); + + fseek (wadfile, 0, SEEK_SET); + SafeWrite (wadfile, header, sizeof(dheader_t)); + fclose (wadfile); +} + +//============================================================================ + +/* +============= +PrintBSPFileSizes + +Dumps info about current file +============= +*/ +void PrintBSPFileSizes (void) +{ + if (!num_entities) + ParseEntities (); + + printf ("%5i models %7i\n" + ,nummodels, (int)(nummodels*sizeof(dmodel_t))); + printf ("%5i brushes %7i\n" + ,numbrushes, (int)(numbrushes*sizeof(dbrush_t))); + printf ("%5i brushsides %7i\n" + ,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t))); + printf ("%5i planes %7i\n" + ,numplanes, (int)(numplanes*sizeof(dplane_t))); + printf ("%5i texinfo %7i\n" + ,numtexinfo, (int)(numtexinfo*sizeof(texinfo_t))); + printf ("%5i entdata %7i\n", num_entities, entdatasize); + + printf ("\n"); + + printf ("%5i vertexes %7i\n" + ,numvertexes, (int)(numvertexes*sizeof(dvertex_t))); + printf ("%5i nodes %7i\n" + ,numnodes, (int)(numnodes*sizeof(dnode_t))); + printf ("%5i faces %7i\n" + ,numfaces, (int)(numfaces*sizeof(dface_t))); + printf ("%5i leafs %7i\n" + ,numleafs, (int)(numleafs*sizeof(dleaf_t))); + printf ("%5i leaffaces %7i\n" + ,numleaffaces, (int)(numleaffaces*sizeof(dleaffaces[0]))); + printf ("%5i leafbrushes %7i\n" + ,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0]))); + printf ("%5i surfedges %7i\n" + ,numsurfedges, (int)(numsurfedges*sizeof(dsurfedges[0]))); + printf ("%5i edges %7i\n" + ,numedges, (int)(numedges*sizeof(dedge_t))); + printf (" lightdata %7i\n", lightdatasize); + printf (" visdata %7i\n", visdatasize); +} + + +//============================================ + +int num_entities; +entity_t entities[MAX_MAP_ENTITIES]; + +void StripTrailing (char *e) +{ + char *s; + + s = e + strlen(e)-1; + while (s >= e && *s <= 32) + { + *s = 0; + s--; + } +} + +/* +================= +ParseEpair +================= +*/ +epair_t *ParseEpair (void) +{ + epair_t *e; + + e = malloc (sizeof(epair_t)); + memset (e, 0, sizeof(epair_t)); + + if (strlen(token) >= MAX_KEY-1) + Error ("ParseEpar: token too long"); + e->key = copystring(token); + GetToken (false); + if (strlen(token) >= MAX_VALUE-1) + Error ("ParseEpar: token too long"); + e->value = copystring(token); + + // strip trailing spaces + StripTrailing (e->key); + StripTrailing (e->value); + + return e; +} + + +/* +================ +ParseEntity +================ +*/ +qboolean ParseEntity (void) +{ + epair_t *e; + entity_t *mapent; + + if (!GetToken (true)) + return false; + + if (strcmp (token, "{") ) + Error ("ParseEntity: { not found"); + + if (num_entities == MAX_MAP_ENTITIES) + Error ("num_entities == MAX_MAP_ENTITIES"); + + mapent = &entities[num_entities]; + num_entities++; + + do + { + if (!GetToken (true)) + Error ("ParseEntity: EOF without closing brace"); + if (!strcmp (token, "}") ) + break; + e = ParseEpair (); + e->next = mapent->epairs; + mapent->epairs = e; + } while (1); + + return true; +} + +/* +================ +ParseEntities + +Parses the dentdata string into entities +================ +*/ +void ParseEntities (void) +{ + num_entities = 0; + ParseFromMemory (dentdata, entdatasize); + + while (ParseEntity ()) + { + } +} + + +/* +================ +UnparseEntities + +Generates the dentdata string from all the entities +================ +*/ +void UnparseEntities (void) +{ + char *buf, *end; + epair_t *ep; + char line[2048]; + int i; + char key[1024], value[1024]; + + buf = dentdata; + end = buf; + *end = 0; + + for (i=0 ; inext) + { + strcpy (key, ep->key); + StripTrailing (key); + strcpy (value, ep->value); + StripTrailing (value); + + sprintf (line, "\"%s\" \"%s\"\n", key, value); + strcat (end, line); + end += strlen(line); + } + strcat (end,"}\n"); + end += 2; + + if (end > buf + MAX_MAP_ENTSTRING) + Error ("Entity text too long"); + } + entdatasize = end - buf + 1; +} + +void PrintEntity (entity_t *ent) +{ + epair_t *ep; + + printf ("------- entity %p -------\n", ent); + for (ep=ent->epairs ; ep ; ep=ep->next) + { + printf ("%s = %s\n", ep->key, ep->value); + } + +} + +void SetKeyValue (entity_t *ent, char *key, char *value) +{ + epair_t *ep; + + for (ep=ent->epairs ; ep ; ep=ep->next) + if (!strcmp (ep->key, key) ) + { + free (ep->value); + ep->value = copystring(value); + return; + } + ep = malloc (sizeof(*ep)); + ep->next = ent->epairs; + ent->epairs = ep; + ep->key = copystring(key); + ep->value = copystring(value); +} + +char *ValueForKey (entity_t *ent, char *key) +{ + epair_t *ep; + + for (ep=ent->epairs ; ep ; ep=ep->next) + if (!strcmp (ep->key, key) ) + return ep->value; + return ""; +} + +vec_t FloatForKey (entity_t *ent, char *key) +{ + char *k; + + k = ValueForKey (ent, key); + return atof(k); +} + +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec) +{ + char *k; + double v1, v2, v3; + + k = ValueForKey (ent, key); +// scanf into doubles, then assign, so it is vec_t size independent + v1 = v2 = v3 = 0; + sscanf (k, "%lf %lf %lf", &v1, &v2, &v3); + vec[0] = v1; + vec[1] = v2; + vec[2] = v3; +} + + diff --git a/tools/quake2/extra/common/bspfile.h b/tools/quake2/extra/common/bspfile.h new file mode 100644 index 00000000..11eeb031 --- /dev/null +++ b/tools/quake2/extra/common/bspfile.h @@ -0,0 +1,129 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qfiles.h" + + +extern int nummodels; +extern dmodel_t dmodels[MAX_MAP_MODELS]; + +extern int visdatasize; +extern byte dvisdata[MAX_MAP_VISIBILITY]; +extern dvis_t *dvis; + +extern int lightdatasize; +extern byte dlightdata[MAX_MAP_LIGHTING]; + +extern int entdatasize; +extern char dentdata[MAX_MAP_ENTSTRING]; + +extern int numleafs; +extern dleaf_t dleafs[MAX_MAP_LEAFS]; + +extern int numplanes; +extern dplane_t dplanes[MAX_MAP_PLANES]; + +extern int numvertexes; +extern dvertex_t dvertexes[MAX_MAP_VERTS]; + +extern int numnodes; +extern dnode_t dnodes[MAX_MAP_NODES]; + +extern int numtexinfo; +extern texinfo_t texinfo[MAX_MAP_TEXINFO]; + +extern int numfaces; +extern dface_t dfaces[MAX_MAP_FACES]; + +extern int numedges; +extern dedge_t dedges[MAX_MAP_EDGES]; + +extern int numleaffaces; +extern unsigned short dleaffaces[MAX_MAP_LEAFFACES]; + +extern int numleafbrushes; +extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES]; + +extern int numsurfedges; +extern int dsurfedges[MAX_MAP_SURFEDGES]; + +extern int numareas; +extern darea_t dareas[MAX_MAP_AREAS]; + +extern int numareaportals; +extern dareaportal_t dareaportals[MAX_MAP_AREAPORTALS]; + +extern int numbrushes; +extern dbrush_t dbrushes[MAX_MAP_BRUSHES]; + +extern int numbrushsides; +extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES]; + +extern byte dpop[256]; + +void DecompressVis (byte *in, byte *decompressed); +int CompressVis (byte *vis, byte *dest); + +void LoadBSPFile (char *filename); +void LoadBSPFileTexinfo (char *filename); // just for qdata +void WriteBSPFile (char *filename); +void PrintBSPFileSizes (void); + +//=============== + + +typedef struct epair_s +{ + struct epair_s *next; + char *key; + char *value; +} epair_t; + +typedef struct +{ + vec3_t origin; + int firstbrush; + int numbrushes; + epair_t *epairs; + +// only valid for func_areaportals + int areaportalnum; + int portalareas[2]; +} entity_t; + +extern int num_entities; +extern entity_t entities[MAX_MAP_ENTITIES]; + +void ParseEntities (void); +void UnparseEntities (void); + +void SetKeyValue (entity_t *ent, char *key, char *value); +char *ValueForKey (entity_t *ent, char *key); +// will return "" if not present + +vec_t FloatForKey (entity_t *ent, char *key); +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec); + +epair_t *ParseEpair (void); + +void PrintEntity (entity_t *ent); + diff --git a/tools/quake2/extra/common/cmdlib.c b/tools/quake2/extra/common/cmdlib.c new file mode 100644 index 00000000..60f615a0 --- /dev/null +++ b/tools/quake2/extra/common/cmdlib.c @@ -0,0 +1,1055 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// cmdlib.c + +#include "cmdlib.h" +#include +#include + +#ifdef WIN32 +#include +#endif + +#ifdef NeXT +#include +#endif + +#define BASEDIRNAME "quake2" +#define PATHSEPERATOR '/' + +// set these before calling CheckParm +int myargc; +char **myargv; + +char com_token[1024]; +qboolean com_eof; + +qboolean archive; +char archivedir[1024]; + + +/* +=================== +ExpandWildcards + +Mimic unix command line expansion +=================== +*/ +#define MAX_EX_ARGC 1024 +int ex_argc; +char *ex_argv[MAX_EX_ARGC]; +#ifdef _WIN32 +#include "io.h" +void ExpandWildcards (int *argc, char ***argv) +{ + struct _finddata_t fileinfo; + int handle; + int i; + char filename[1024]; + char filebase[1024]; + char *path; + + ex_argc = 0; + for (i=0 ; i<*argc ; i++) + { + path = (*argv)[i]; + if ( path[0] == '-' + || ( !strstr(path, "*") && !strstr(path, "?") ) ) + { + ex_argv[ex_argc++] = path; + continue; + } + + handle = _findfirst (path, &fileinfo); + if (handle == -1) + return; + + ExtractFilePath (path, filebase); + + do + { + sprintf (filename, "%s%s", filebase, fileinfo.name); + ex_argv[ex_argc++] = copystring (filename); + } while (_findnext( handle, &fileinfo ) != -1); + + _findclose (handle); + } + + *argc = ex_argc; + *argv = ex_argv; +} +#else +void ExpandWildcards (int *argc, char ***argv) +{ +} +#endif + +#ifdef WIN_ERROR +#include +/* +================= +Error + +For abnormal program terminations in windowed apps +================= +*/ +void Error (char *error, ...) +{ + va_list argptr; + char text[1024]; + char text2[1024]; + int err; + + err = GetLastError (); + + va_start (argptr,error); + vsprintf (text, error,argptr); + va_end (argptr); + + sprintf (text2, "%s\nGetLastError() = %i", text, err); + MessageBox(NULL, text2, "Error", 0 /* MB_OK */ ); + + exit (1); +} + +#else +/* +================= +Error + +For abnormal program terminations in console apps +================= +*/ +void Error (char *error, ...) +{ + va_list argptr; + + printf ("\n************ ERROR ************\n"); + + va_start (argptr,error); + vprintf (error,argptr); + va_end (argptr); + printf ("\n"); + + exit (1); +} +#endif + +// only printf if in verbose mode +qboolean verbose = false; +void qprintf (char *format, ...) +{ + va_list argptr; + + if (!verbose) + return; + + va_start (argptr,format); + vprintf (format,argptr); + va_end (argptr); +} + + +/* + +qdir will hold the path up to the quake directory, including the slash + + f:\quake\ + /raid/quake/ + +gamedir will hold qdir + the game directory (id1, id2, etc) + + */ + +char qdir[1024]; +char gamedir[1024]; + +void SetQdirFromPath (char *path) +{ + char temp[1024]; + char *c; + int len; + + if (!(path[0] == '/' || path[0] == '\\' || path[1] == ':')) + { // path is partial + Q_getwd (temp); + strcat (temp, path); + path = temp; + } + + // search for "quake2" in path + + len = strlen(BASEDIRNAME); + for (c=path+strlen(path)-1 ; c != path ; c--) + if (!Q_strncasecmp (c, BASEDIRNAME, len)) + { + strncpy (qdir, path, c+len+1-path); + qprintf ("qdir: %s\n", qdir); + c += len+1; + while (*c) + { + if (*c == '/' || *c == '\\') + { + strncpy (gamedir, path, c+1-path); + qprintf ("gamedir: %s\n", gamedir); + return; + } + c++; + } + Error ("No gamedir in %s", path); + return; + } + Error ("SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path); +} + +char *ExpandArg (char *path) +{ + static char full[1024]; + + if (path[0] != '/' && path[0] != '\\' && path[1] != ':') + { + Q_getwd (full); + strcat (full, path); + } + else + strcpy (full, path); + return full; +} + +char *ExpandPath (char *path) +{ + static char full[1024]; + if (!qdir) + Error ("ExpandPath called without qdir set"); + if (path[0] == '/' || path[0] == '\\' || path[1] == ':') + return path; + sprintf (full, "%s%s", qdir, path); + return full; +} + +char *ExpandPathAndArchive (char *path) +{ + char *expanded; + char archivename[1024]; + + expanded = ExpandPath (path); + + if (archive) + { + sprintf (archivename, "%s/%s", archivedir, path); + QCopyFile (expanded, archivename); + } + return expanded; +} + + +char *copystring(char *s) +{ + char *b; + b = malloc(strlen(s)+1); + strcpy (b, s); + return b; +} + + + +/* +================ +I_FloatTime +================ +*/ +double I_FloatTime (void) +{ + time_t t; + + time (&t); + + return t; +#if 0 +// more precise, less portable + struct timeval tp; + struct timezone tzp; + static int secbase; + + gettimeofday(&tp, &tzp); + + if (!secbase) + { + secbase = tp.tv_sec; + return tp.tv_usec/1000000.0; + } + + return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; +#endif +} + +void Q_getwd (char *out) +{ +#ifdef WIN32 + _getcwd (out, 256); + strcat (out, "\\"); +#else + getwd (out); + strcat (out, "/"); +#endif +} + + +void Q_mkdir (char *path) +{ +#ifdef WIN32 + if (_mkdir (path) != -1) + return; +#else + if (mkdir (path, 0777) != -1) + return; +#endif + if (errno != EEXIST) + Error ("mkdir %s: %s",path, strerror(errno)); +} + +/* +============ +FileTime + +returns -1 if not present +============ +*/ +int FileTime (char *path) +{ + struct stat buf; + + if (stat (path,&buf) == -1) + return -1; + + return buf.st_mtime; +} + + + +/* +============== +COM_Parse + +Parse a token out of a string +============== +*/ +char *COM_Parse (char *data) +{ + int c; + int len; + + len = 0; + com_token[0] = 0; + + if (!data) + return NULL; + +// skip whitespace +skipwhite: + while ( (c = *data) <= ' ') + { + if (c == 0) + { + com_eof = true; + return NULL; // end of file; + } + data++; + } + +// skip // comments + if (c=='/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + + +// handle quoted strings specially + if (c == '\"') + { + data++; + do + { + c = *data++; + if (c=='\"') + { + com_token[len] = 0; + return data; + } + com_token[len] = c; + len++; + } while (1); + } + +// parse single characters + if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') + { + com_token[len] = c; + len++; + com_token[len] = 0; + return data+1; + } + +// parse a regular word + do + { + com_token[len] = c; + data++; + len++; + c = *data; + if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') + break; + } while (c>32); + + com_token[len] = 0; + return data; +} + + +int Q_strncasecmp (char *s1, char *s2, int n) +{ + int c1, c2; + + do + { + c1 = *s1++; + c2 = *s2++; + + if (!n--) + return 0; // strings are equal until end point + + if (c1 != c2) + { + if (c1 >= 'a' && c1 <= 'z') + c1 -= ('a' - 'A'); + if (c2 >= 'a' && c2 <= 'z') + c2 -= ('a' - 'A'); + if (c1 != c2) + return -1; // strings not equal + } + } while (c1); + + return 0; // strings are equal +} + +int Q_strcasecmp (char *s1, char *s2) +{ + return Q_strncasecmp (s1, s2, 99999); +} + + +char *strupr (char *start) +{ + char *in; + in = start; + while (*in) + { + *in = toupper(*in); + in++; + } + return start; +} + +char *strlower (char *start) +{ + char *in; + in = start; + while (*in) + { + *in = tolower(*in); + in++; + } + return start; +} + + +/* +============================================================================= + + MISC FUNCTIONS + +============================================================================= +*/ + + +/* +================= +CheckParm + +Checks for the given parameter in the program's command line arguments +Returns the argument number (1 to argc-1) or 0 if not present +================= +*/ +int CheckParm (char *check) +{ + int i; + + for (i = 1;i 0 && path[length] != PATHSEPERATOR) + length--; + path[length] = 0; +} + +void StripExtension (char *path) +{ + int length; + + length = strlen(path)-1; + while (length > 0 && path[length] != '.') + { + length--; + if (path[length] == '/') + return; // no extension + } + if (length) + path[length] = 0; +} + + +/* +==================== +Extract file parts +==================== +*/ +// FIXME: should include the slash, otherwise +// backing to an empty path will be wrong when appending a slash +void ExtractFilePath (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// + while (src != path && *(src-1) != '\\' && *(src-1) != '/') + src--; + + memcpy (dest, path, src-path); + dest[src-path] = 0; +} + +void ExtractFileBase (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// + while (src != path && *(src-1) != PATHSEPERATOR) + src--; + + while (*src && *src != '.') + { + *dest++ = *src++; + } + *dest = 0; +} + +void ExtractFileExtension (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a . or the start +// + while (src != path && *(src-1) != '.') + src--; + if (src == path) + { + *dest = 0; // no extension + return; + } + + strcpy (dest,src); +} + + +/* +============== +ParseNum / ParseHex +============== +*/ +int ParseHex (char *hex) +{ + char *str; + int num; + + num = 0; + str = hex; + + while (*str) + { + num <<= 4; + if (*str >= '0' && *str <= '9') + num += *str-'0'; + else if (*str >= 'a' && *str <= 'f') + num += 10 + *str-'a'; + else if (*str >= 'A' && *str <= 'F') + num += 10 + *str-'A'; + else + Error ("Bad hex number: %s",hex); + str++; + } + + return num; +} + + +int ParseNum (char *str) +{ + if (str[0] == '$') + return ParseHex (str+1); + if (str[0] == '0' && str[1] == 'x') + return ParseHex (str+2); + return atol (str); +} + + + +/* +============================================================================ + + BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +#ifdef _SGI_SOURCE +#define __BIG_ENDIAN__ +#endif + +#ifdef __BIG_ENDIAN__ + +short LittleShort (short l) +{ + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short BigShort (short l) +{ + return l; +} + + +int LittleLong (int l) +{ + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int BigLong (int l) +{ + return l; +} + + +float LittleFloat (float l) +{ + union {byte b[4]; float f;} in, out; + + in.f = l; + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + return out.f; +} + +float BigFloat (float l) +{ + return l; +} + + +#else + + +short BigShort (short l) +{ + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short LittleShort (short l) +{ + return l; +} + + +int BigLong (int l) +{ + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int LittleLong (int l) +{ + return l; +} + +float BigFloat (float l) +{ + union {byte b[4]; float f;} in, out; + + in.f = l; + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + return out.f; +} + +float LittleFloat (float l) +{ + return l; +} + + +#endif + + +//======================================================= + + +// FIXME: byte swap? + +// this is a 16 bit, non-reflected CRC using the polynomial 0x1021 +// and the initial and final xor values shown below... in other words, the +// CCITT standard CRC used by XMODEM + +#define CRC_INIT_VALUE 0xffff +#define CRC_XOR_VALUE 0x0000 + +static unsigned short crctable[256] = +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + +void CRC_Init(unsigned short *crcvalue) +{ + *crcvalue = CRC_INIT_VALUE; +} + +void CRC_ProcessByte(unsigned short *crcvalue, byte data) +{ + *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data]; +} + +unsigned short CRC_Value(unsigned short crcvalue) +{ + return crcvalue ^ CRC_XOR_VALUE; +} +//============================================================================= + +/* +============ +CreatePath +============ +*/ +void CreatePath (char *path) +{ + char *ofs, c; + + if (path[1] == ':') + path += 2; + + for (ofs = path+1 ; *ofs ; ofs++) + { + c = *ofs; + if (c == '/' || c == '\\') + { // create the directory + *ofs = 0; + Q_mkdir (path); + *ofs = c; + } + } +} + + +/* +============ +QCopyFile + + Used to archive source files +============ +*/ +void QCopyFile (char *from, char *to) +{ + void *buffer; + int length; + + length = LoadFile (from, &buffer); + CreatePath (to); + SaveFile (to, buffer, length); + free (buffer); +} diff --git a/tools/quake2/extra/common/cmdlib.h b/tools/quake2/extra/common/cmdlib.h new file mode 100644 index 00000000..0045a09d --- /dev/null +++ b/tools/quake2/extra/common/cmdlib.h @@ -0,0 +1,145 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// cmdlib.h + +#ifndef __CMDLIB__ +#define __CMDLIB__ + +#ifdef _WIN32 +#pragma warning(disable : 4244) // MIPS +#pragma warning(disable : 4136) // X86 +#pragma warning(disable : 4051) // ALPHA + +#pragma warning(disable : 4018) // signed/unsigned mismatch +#pragma warning(disable : 4305) // truncate from double to float +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifndef __BYTEBOOL__ +#define __BYTEBOOL__ +typedef enum {false, true} qboolean; +typedef unsigned char byte; +#endif + +// the dec offsetof macro doesnt work very well... +#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier) + + +// set these before calling CheckParm +extern int myargc; +extern char **myargv; + +char *strupr (char *in); +char *strlower (char *in); +int Q_strncasecmp (char *s1, char *s2, int n); +int Q_strcasecmp (char *s1, char *s2); +void Q_getwd (char *out); + +int Q_filelength (FILE *f); +int FileTime (char *path); + +void Q_mkdir (char *path); + +extern char qdir[1024]; +extern char gamedir[1024]; +void SetQdirFromPath (char *path); +char *ExpandArg (char *path); // from cmd line +char *ExpandPath (char *path); // from scripts +char *ExpandPathAndArchive (char *path); + + +double I_FloatTime (void); + +void Error (char *error, ...); +int CheckParm (char *check); + +FILE *SafeOpenWrite (char *filename); +FILE *SafeOpenRead (char *filename); +void SafeRead (FILE *f, void *buffer, int count); +void SafeWrite (FILE *f, void *buffer, int count); + +int LoadFile (char *filename, void **bufferptr); +int TryLoadFile (char *filename, void **bufferptr); +void SaveFile (char *filename, void *buffer, int count); +qboolean FileExists (char *filename); + +void DefaultExtension (char *path, char *extension); +void DefaultPath (char *path, char *basepath); +void StripFilename (char *path); +void StripExtension (char *path); + +void ExtractFilePath (char *path, char *dest); +void ExtractFileBase (char *path, char *dest); +void ExtractFileExtension (char *path, char *dest); + +int ParseNum (char *str); + +short BigShort (short l); +short LittleShort (short l); +int BigLong (int l); +int LittleLong (int l); +float BigFloat (float l); +float LittleFloat (float l); + + +char *COM_Parse (char *data); + +extern char com_token[1024]; +extern qboolean com_eof; + +char *copystring(char *s); + + +void CRC_Init(unsigned short *crcvalue); +void CRC_ProcessByte(unsigned short *crcvalue, byte data); +unsigned short CRC_Value(unsigned short crcvalue); + +void CreatePath (char *path); +void QCopyFile (char *from, char *to); + +extern qboolean archive; +extern char archivedir[1024]; + + +extern qboolean verbose; +void qprintf (char *format, ...); + +void ExpandWildcards (int *argc, char ***argv); + + +// for compression routines +typedef struct +{ + byte *data; + int count; +} cblock_t; + + +#endif diff --git a/tools/quake2/extra/common/l3dslib.c b/tools/quake2/extra/common/l3dslib.c new file mode 100644 index 00000000..8441f4af --- /dev/null +++ b/tools/quake2/extra/common/l3dslib.c @@ -0,0 +1,301 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// +// l3dslib.c: library for loading triangles from an Alias triangle file +// + +#include +#include "cmdlib.h" +#include "mathlib.h" +#include "trilib.h" +#include "l3dslib.h" + +#define MAIN3DS 0x4D4D +#define EDIT3DS 0x3D3D // this is the start of the editor config +#define EDIT_OBJECT 0x4000 +#define OBJ_TRIMESH 0x4100 +#define TRI_VERTEXL 0x4110 +#define TRI_FACEL1 0x4120 + +#define MAXVERTS 2000 + +typedef struct { + int v[4]; +} tri; + +float fverts[MAXVERTS][3]; +tri tris[MAXTRIANGLES]; + +int bytesread, level, numtris, totaltris; +int vertsfound, trisfound; + +triangle_t *ptri; + + +// Alias stores triangles as 3 explicit vertices in .tri files, so even though we +// start out with a vertex pool and vertex indices for triangles, we have to convert +// to raw, explicit triangles +void StoreAliasTriangles (void) +{ + int i, j, k; + + if ((totaltris + numtris) > MAXTRIANGLES) + Error ("Error: Too many triangles"); + + for (i=0; i MAXVERTS) + Error ("Error: Too many vertices"); + + for (i=0 ; i MAXTRIANGLES) + Error ("Error: Too many triangles"); + + for (i=0 ; i 0) + { + w -= ParseChunk (input); + } + + retval = length; + goto Done; + + default: + // skip other chunks + while (w > 0) + { + t = w; + + if (t > BLOCK_SIZE) + t = BLOCK_SIZE; + + if (feof(input)) + Error ("Error: unexpected end of file"); + + fread (&temp, t, 1, input); + bytesread += t; + + w -= t; + } + + retval = length; + goto Done; + } + +Done: + level--; + return retval; +} + + +void Load3DSTriangleList (char *filename, triangle_t **pptri, int *numtriangles) +{ + FILE *input; + short int tshort; + + bytesread = 0; + level = 0; + numtris = 0; + totaltris = 0; + vertsfound = 0; + trisfound = 0; + + if ((input = fopen(filename, "rb")) == 0) { + fprintf(stderr,"reader: could not open file '%s'\n", filename); + exit(0); + } + + fread(&tshort, sizeof(tshort), 1, input); + +// should only be MAIN3DS, but some files seem to start with EDIT3DS, with +// no MAIN3DS + if ((tshort != MAIN3DS) && (tshort != EDIT3DS)) { + fprintf(stderr,"File is not a 3DS file.\n"); + exit(0); + } + +// back to top of file so we can parse the first chunk descriptor + fseek(input, 0, SEEK_SET); + + ptri = malloc (MAXTRIANGLES * sizeof(triangle_t)); + + *pptri = ptri; + +// parse through looking for the relevant chunk tree (MAIN3DS | EDIT3DS | EDIT_OBJECT | +// OBJ_TRIMESH | {TRI_VERTEXL, TRI_FACEL1}) and skipping other chunks + ParseChunk (input); + + if (vertsfound || trisfound) + Error ("Incomplete triangle set"); + + *numtriangles = totaltris; + + fclose (input); +} + diff --git a/tools/quake2/extra/common/l3dslib.h b/tools/quake2/extra/common/l3dslib.h new file mode 100644 index 00000000..d28871f1 --- /dev/null +++ b/tools/quake2/extra/common/l3dslib.h @@ -0,0 +1,27 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// +// l3dslib.h: header file for loading triangles from a 3DS triangle file +// +void Load3DSTriangleList (char *filename, triangle_t **pptri, int *numtriangles); + diff --git a/tools/quake2/extra/common/lbmlib.c b/tools/quake2/extra/common/lbmlib.c new file mode 100644 index 00000000..25793534 --- /dev/null +++ b/tools/quake2/extra/common/lbmlib.c @@ -0,0 +1,824 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// lbmlib.c + +#include "cmdlib.h" +#include "lbmlib.h" + + + +/* +============================================================================ + + LBM STUFF + +============================================================================ +*/ + + +typedef unsigned char UBYTE; +//conflicts with windows typedef short WORD; +typedef unsigned short UWORD; +typedef long LONG; + +typedef enum +{ + ms_none, + ms_mask, + ms_transcolor, + ms_lasso +} mask_t; + +typedef enum +{ + cm_none, + cm_rle1 +} compress_t; + +typedef struct +{ + UWORD w,h; + short x,y; + UBYTE nPlanes; + UBYTE masking; + UBYTE compression; + UBYTE pad1; + UWORD transparentColor; + UBYTE xAspect,yAspect; + short pageWidth,pageHeight; +} bmhd_t; + +extern bmhd_t bmhd; // will be in native byte order + + + +#define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24)) +#define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24)) +#define PBMID ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24)) +#define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24)) +#define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24)) +#define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24)) + + +bmhd_t bmhd; + +int Align (int l) +{ + if (l&1) + return l+1; + return l; +} + + + +/* +================ +LBMRLEdecompress + +Source must be evenly aligned! +================ +*/ +byte *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth) +{ + int count; + byte b,rept; + + count = 0; + + do + { + rept = *source++; + + if (rept > 0x80) + { + rept = (rept^0xff)+2; + b = *source++; + memset(unpacked,b,rept); + unpacked += rept; + } + else if (rept < 0x80) + { + rept++; + memcpy(unpacked,source,rept); + unpacked += rept; + source += rept; + } + else + rept = 0; // rept of 0x80 is NOP + + count += rept; + + } while (countbpwidth) + Error ("Decompression exceeded width!\n"); + + + return source; +} + + +/* +================= +LoadLBM +================= +*/ +void LoadLBM (char *filename, byte **picture, byte **palette) +{ + byte *LBMbuffer, *picbuffer, *cmapbuffer; + int y; + byte *LBM_P, *LBMEND_P; + byte *pic_p; + byte *body_p; + + int formtype,formlength; + int chunktype,chunklength; + +// qiet compiler warnings + picbuffer = NULL; + cmapbuffer = NULL; + +// +// load the LBM +// + LoadFile (filename, (void **)&LBMbuffer); + +// +// parse the LBM header +// + LBM_P = LBMbuffer; + if ( *(int *)LBMbuffer != LittleLong(FORMID) ) + Error ("No FORM ID at start of file!\n"); + + LBM_P += 4; + formlength = BigLong( *(int *)LBM_P ); + LBM_P += 4; + LBMEND_P = LBM_P + Align(formlength); + + formtype = LittleLong(*(int *)LBM_P); + + if (formtype != ILBMID && formtype != PBMID) + Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff + ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff); + + LBM_P += 4; + +// +// parse chunks +// + + while (LBM_P < LBMEND_P) + { + chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24); + LBM_P += 4; + chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24); + LBM_P += 4; + + switch ( chunktype ) + { + case BMHDID: + memcpy (&bmhd,LBM_P,sizeof(bmhd)); + bmhd.w = BigShort(bmhd.w); + bmhd.h = BigShort(bmhd.h); + bmhd.x = BigShort(bmhd.x); + bmhd.y = BigShort(bmhd.y); + bmhd.pageWidth = BigShort(bmhd.pageWidth); + bmhd.pageHeight = BigShort(bmhd.pageHeight); + break; + + case CMAPID: + cmapbuffer = malloc (768); + memset (cmapbuffer, 0, 768); + memcpy (cmapbuffer, LBM_P, chunklength); + break; + + case BODYID: + body_p = LBM_P; + + pic_p = picbuffer = malloc (bmhd.w*bmhd.h); + if (formtype == PBMID) + { + // + // unpack PBM + // + for (y=0 ; ydata; + + pcx->xmin = LittleShort(pcx->xmin); + pcx->ymin = LittleShort(pcx->ymin); + pcx->xmax = LittleShort(pcx->xmax); + pcx->ymax = LittleShort(pcx->ymax); + pcx->hres = LittleShort(pcx->hres); + pcx->vres = LittleShort(pcx->vres); + pcx->bytes_per_line = LittleShort(pcx->bytes_per_line); + pcx->palette_type = LittleShort(pcx->palette_type); + + if (pcx->manufacturer != 0x0a + || pcx->version != 5 + || pcx->encoding != 1 + || pcx->bits_per_pixel != 8 + || pcx->xmax >= 640 + || pcx->ymax >= 480) + Error ("Bad pcx file %s", filename); + + if (palette) + { + *palette = malloc(768); + memcpy (*palette, (byte *)pcx + len - 768, 768); + } + + if (width) + *width = pcx->xmax+1; + if (height) + *height = pcx->ymax+1; + + if (!pic) + return; + + out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) ); + if (!out) + Error ("Skin_Cache: couldn't allocate"); + + *pic = out; + + pix = out; + + for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1) + { + for (x=0 ; x<=pcx->xmax ; ) + { + dataByte = *raw++; + + if((dataByte & 0xC0) == 0xC0) + { + runLength = dataByte & 0x3F; + dataByte = *raw++; + } + else + runLength = 1; + + while(runLength-- > 0) + pix[x++] = dataByte; + } + + } + + if ( raw - (byte *)pcx > len) + Error ("PCX file %s was malformed", filename); + + free (pcx); +} + +/* +============== +WritePCXfile +============== +*/ +void WritePCXfile (char *filename, byte *data, + int width, int height, byte *palette) +{ + int i, j, length; + pcx_t *pcx; + byte *pack; + + pcx = malloc (width*height*2+1000); + memset (pcx, 0, sizeof(*pcx)); + + pcx->manufacturer = 0x0a; // PCX id + pcx->version = 5; // 256 color + pcx->encoding = 1; // uncompressed + pcx->bits_per_pixel = 8; // 256 color + pcx->xmin = 0; + pcx->ymin = 0; + pcx->xmax = LittleShort((short)(width-1)); + pcx->ymax = LittleShort((short)(height-1)); + pcx->hres = LittleShort((short)width); + pcx->vres = LittleShort((short)height); + pcx->color_planes = 1; // chunky image + pcx->bytes_per_line = LittleShort((short)width); + pcx->palette_type = LittleShort(2); // not a grey scale + + // pack the image + pack = &pcx->data; + + for (i=0 ; i=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + else { // non run-length packet + for(j=0;j0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut:; + } + } + + fclose(fin); +} diff --git a/tools/quake2/extra/common/lbmlib.h b/tools/quake2/extra/common/lbmlib.h new file mode 100644 index 00000000..c90a6dd8 --- /dev/null +++ b/tools/quake2/extra/common/lbmlib.h @@ -0,0 +1,40 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// piclib.h + + +void LoadLBM (char *filename, byte **picture, byte **palette); +void WriteLBMfile (char *filename, byte *data, int width, int height + , byte *palette); +void LoadPCX (char *filename, byte **picture, byte **palette, int *width, int *height); +void WritePCXfile (char *filename, byte *data, int width, int height + , byte *palette); + +// loads / saves either lbm or pcx, depending on extension +void Load256Image (char *name, byte **pixels, byte **palette, + int *width, int *height); +void Save256Image (char *name, byte *pixels, byte *palette, + int width, int height); + + +void LoadTGA (char *filename, byte **pixels, int *width, int *height); diff --git a/tools/quake2/extra/common/mathlib.c b/tools/quake2/extra/common/mathlib.c new file mode 100644 index 00000000..207027b3 --- /dev/null +++ b/tools/quake2/extra/common/mathlib.c @@ -0,0 +1,174 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// mathlib.c -- math primitives + +#include "cmdlib.h" +#include "mathlib.h" + +vec3_t vec3_origin = {0,0,0}; + + +double VectorLength(vec3_t v) +{ + int i; + double length; + + length = 0; + for (i=0 ; i< 3 ; i++) + length += v[i]*v[i]; + length = sqrt (length); // FIXME + + return length; +} + +qboolean VectorCompare (vec3_t v1, vec3_t v2) +{ + int i; + + for (i=0 ; i<3 ; i++) + if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON) + return false; + + return true; +} + +vec_t Q_rint (vec_t in) +{ + return floor (in + 0.5); +} + +void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc) +{ + vc[0] = va[0] + scale*vb[0]; + vc[1] = va[1] + scale*vb[1]; + vc[2] = va[2] + scale*vb[2]; +} + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +{ + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +vec_t _DotProduct (vec3_t v1, vec3_t v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out) +{ + out[0] = va[0]-vb[0]; + out[1] = va[1]-vb[1]; + out[2] = va[2]-vb[2]; +} + +void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out) +{ + out[0] = va[0]+vb[0]; + out[1] = va[1]+vb[1]; + out[2] = va[2]+vb[2]; +} + +void _VectorCopy (vec3_t in, vec3_t out) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +void _VectorScale (vec3_t v, vec_t scale, vec3_t out) +{ + out[0] = v[0] * scale; + out[1] = v[1] * scale; + out[2] = v[2] * scale; +} + +vec_t VectorNormalize (vec3_t in, vec3_t out) +{ + vec_t length, ilength; + + length = sqrt (in[0]*in[0] + in[1]*in[1] + in[2]*in[2]); + if (length == 0) + { + VectorClear (out); + return 0; + } + + ilength = 1.0/length; + out[0] = in[0]*ilength; + out[1] = in[1]*ilength; + out[2] = in[2]*ilength; + + return length; +} + +vec_t ColorNormalize (vec3_t in, vec3_t out) +{ + float max, scale; + + max = in[0]; + if (in[1] > max) + max = in[1]; + if (in[2] > max) + max = in[2]; + + if (max == 0) + return 0; + + scale = 1.0 / max; + + VectorScale (in, scale, out); + + return max; +} + + + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void ClearBounds (vec3_t mins, vec3_t maxs) +{ + mins[0] = mins[1] = mins[2] = 99999; + maxs[0] = maxs[1] = maxs[2] = -99999; +} + +void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs) +{ + int i; + vec_t val; + + for (i=0 ; i<3 ; i++) + { + val = v[i]; + if (val < mins[i]) + mins[i] = val; + if (val > maxs[i]) + maxs[i] = val; + } +} diff --git a/tools/quake2/extra/common/mathlib.h b/tools/quake2/extra/common/mathlib.h new file mode 100644 index 00000000..ee7fddee --- /dev/null +++ b/tools/quake2/extra/common/mathlib.h @@ -0,0 +1,77 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#ifndef __MATHLIB__ +#define __MATHLIB__ + +// mathlib.h + +#include + +#ifdef DOUBLEVEC_T +typedef double vec_t; +#else +typedef float vec_t; +#endif +typedef vec_t vec3_t[3]; + +#define SIDE_FRONT 0 +#define SIDE_ON 2 +#define SIDE_BACK 1 +#define SIDE_CROSS -2 + +#define Q_PI 3.14159265358979323846 + +extern vec3_t vec3_origin; + +#define EQUAL_EPSILON 0.001 + +qboolean VectorCompare (vec3_t v1, vec3_t v2); + +#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) +#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];} +#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];} +#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];} +#define VectorScale(a,b,c) {c[0]=b*a[0];c[1]=b*a[1];c[2]=b*a[2];} +#define VectorClear(x) {x[0] = x[1] = x[2] = 0;} +#define VectorNegate(x) {x[0]=-x[0];x[1]=-x[1];x[2]=-x[2];} + +vec_t Q_rint (vec_t in); +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out); +void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out); +void _VectorCopy (vec3_t in, vec3_t out); +void _VectorScale (vec3_t v, vec_t scale, vec3_t out); + +double VectorLength(vec3_t v); + +void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc); + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +vec_t VectorNormalize (vec3_t in, vec3_t out); +vec_t ColorNormalize (vec3_t in, vec3_t out); +void VectorInverse (vec3_t v); + +void ClearBounds (vec3_t mins, vec3_t maxs); +void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); + +#endif diff --git a/tools/quake2/extra/common/mdfour.c b/tools/quake2/extra/common/mdfour.c new file mode 100644 index 00000000..f5b9a29d --- /dev/null +++ b/tools/quake2/extra/common/mdfour.c @@ -0,0 +1,224 @@ +/* + mdfour.c + + An implementation of MD4 designed for use in the samba SMB + authentication protocol + + Copyright (C) 1997-1998 Andrew Tridgell + + 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: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id: mdfour.c,v 1.1 2002/08/23 22:03:27 abster Exp $ +*/ + +#include /* XoXus: needed for memset call */ +#include "mdfour.h" + +/* NOTE: This code makes no attempt to be fast! + + It assumes that a int is at least 32 bits long +*/ + +static struct mdfour *m; + +#define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z))) +#define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))) +#define H(X,Y,Z) ((X)^(Y)^(Z)) +#ifdef LARGE_INT32 +#define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF)) +#else +#define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s)))) +#endif + +#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) +#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s) +#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s) + +/* this applies md4 to 64 byte chunks */ +static void mdfour64(uint32 *M) +{ + int j; + uint32 AA, BB, CC, DD; + uint32 X[16]; + uint32 A,B,C,D; + + for (j=0;j<16;j++) + X[j] = M[j]; + + A = m->A; B = m->B; C = m->C; D = m->D; + AA = A; BB = B; CC = C; DD = D; + + ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); + ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); + ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); + ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); + ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); + ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); + ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); + ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); + + ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); + ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); + ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); + ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); + ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); + ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); + ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); + ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); + + ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); + ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); + ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); + ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); + ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); + ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); + ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); + ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); + + A += AA; B += BB; C += CC; D += DD; + +#ifdef LARGE_INT32 + A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; + C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; +#endif + + for (j=0;j<16;j++) + X[j] = 0; + + m->A = A; m->B = B; m->C = C; m->D = D; +} + +static void copy64(uint32 *M, unsigned char *in) +{ + int i; + + for (i=0;i<16;i++) + M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | + (in[i*4+1]<<8) | (in[i*4+0]<<0); +} + +static void copy4(unsigned char *out,uint32 x) +{ + out[0] = x&0xFF; + out[1] = (x>>8)&0xFF; + out[2] = (x>>16)&0xFF; + out[3] = (x>>24)&0xFF; +} + +void mdfour_begin(struct mdfour *md) +{ + md->A = 0x67452301; + md->B = 0xefcdab89; + md->C = 0x98badcfe; + md->D = 0x10325476; + md->totalN = 0; +} + + +static void mdfour_tail(unsigned char *in, int n) +{ + unsigned char buf[128]; + uint32 M[16]; + uint32 b; + + m->totalN += n; + + b = m->totalN * 8; + + memset(buf, 0, 128); + if (n) memcpy(buf, in, n); + buf[n] = 0x80; + + if (n <= 55) { + copy4(buf+56, b); + copy64(M, buf); + mdfour64(M); + } else { + copy4(buf+120, b); + copy64(M, buf); + mdfour64(M); + copy64(M, buf+64); + mdfour64(M); + } +} + +void mdfour_update(struct mdfour *md, unsigned char *in, int n) +{ + uint32 M[16]; + + if (n == 0) mdfour_tail(in, n); + + m = md; + + while (n >= 64) { + copy64(M, in); + mdfour64(M); + in += 64; + n -= 64; + m->totalN += 64; + } + + mdfour_tail(in, n); +} + + +void mdfour_result(struct mdfour *md, unsigned char *out) +{ + m = md; + + copy4(out, m->A); + copy4(out+4, m->B); + copy4(out+8, m->C); + copy4(out+12, m->D); +} + + +void mdfour(unsigned char *out, unsigned char *in, int n) +{ + struct mdfour md; + mdfour_begin(&md); + mdfour_update(&md, in, n); + mdfour_result(&md, out); +} + +/////////////////////////////////////////////////////////////// +// MD4-based checksum utility functions +// +// Copyright (C) 2000 Jeff Teunissen +// +// Author: Jeff Teunissen +// Date: 01 Jan 2000 + +unsigned Com_BlockChecksum (void *buffer, int length) +{ + int digest[4]; + unsigned val; + + mdfour ( (unsigned char *) digest, (unsigned char *) buffer, length ); + + val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; + + return val; +} + +void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf) +{ + mdfour ( outbuf, (unsigned char *) buffer, len ); +} + diff --git a/tools/quake2/extra/common/mdfour.h b/tools/quake2/extra/common/mdfour.h new file mode 100644 index 00000000..69ca6f78 --- /dev/null +++ b/tools/quake2/extra/common/mdfour.h @@ -0,0 +1,54 @@ +/* + mdfour.h + + an implementation of MD4 designed for use in the SMB authentication + protocol + + Copyright (C) Andrew Tridgell 1997-1998 + + 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: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA +*/ + +#ifndef _MDFOUR_H +#define _MDFOUR_H + +#ifndef int32 +#define int32 int +#endif + +#if SIZEOF_INT > 4 +#define LARGE_INT32 +#endif + +#ifndef uint32 +#define uint32 unsigned int32 +#endif + +struct mdfour { + uint32 A, B, C, D; + uint32 totalN; +}; + +void mdfour_begin(struct mdfour *md); // old: MD4Init +void mdfour_update(struct mdfour *md, unsigned char *in, int n); //old: MD4Update +void mdfour_result(struct mdfour *md, unsigned char *out); // old: MD4Final +void mdfour(unsigned char *out, unsigned char *in, int n); + +#endif // _MDFOUR_H + diff --git a/tools/quake2/extra/common/polylib.c b/tools/quake2/extra/common/polylib.c new file mode 100644 index 00000000..c190ebd6 --- /dev/null +++ b/tools/quake2/extra/common/polylib.c @@ -0,0 +1,642 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "cmdlib.h" +#include "mathlib.h" +#include "polylib.h" + + +extern int numthreads; + +// counters are only bumped when running single threaded, +// because they are an awefull coherence problem +int c_active_windings; +int c_peak_windings; +int c_winding_allocs; +int c_winding_points; + +#define BOGUS_RANGE 8192 + +void pw(winding_t *w) +{ + int i; + for (i=0 ; inumpoints ; i++) + printf ("(%5.1f, %5.1f, %5.1f)\n",w->p[i][0], w->p[i][1],w->p[i][2]); +} + + +/* +============= +AllocWinding +============= +*/ +winding_t *AllocWinding (int points) +{ + winding_t *w; + int s; + + if (numthreads == 1) + { + c_winding_allocs++; + c_winding_points += points; + c_active_windings++; + if (c_active_windings > c_peak_windings) + c_peak_windings = c_active_windings; + } + s = sizeof(vec_t)*3*points + sizeof(int); + w = malloc (s); + memset (w, 0, s); + return w; +} + +void FreeWinding (winding_t *w) +{ + if (*(unsigned *)w == 0xdeaddead) + Error ("FreeWinding: freed a freed winding"); + *(unsigned *)w = 0xdeaddead; + + if (numthreads == 1) + c_active_windings--; + free (w); +} + +/* +============ +RemoveColinearPoints +============ +*/ +int c_removed; + +void RemoveColinearPoints (winding_t *w) +{ + int i, j, k; + vec3_t v1, v2; + int nump; + vec3_t p[MAX_POINTS_ON_WINDING]; + + nump = 0; + for (i=0 ; inumpoints ; i++) + { + j = (i+1)%w->numpoints; + k = (i+w->numpoints-1)%w->numpoints; + VectorSubtract (w->p[j], w->p[i], v1); + VectorSubtract (w->p[i], w->p[k], v2); + VectorNormalize(v1,v1); + VectorNormalize(v2,v2); + if (DotProduct(v1, v2) < 0.999) + { + VectorCopy (w->p[i], p[nump]); + nump++; + } + } + + if (nump == w->numpoints) + return; + + if (numthreads == 1) + c_removed += w->numpoints - nump; + w->numpoints = nump; + memcpy (w->p, p, nump*sizeof(p[0])); +} + +/* +============ +WindingPlane +============ +*/ +void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist) +{ + vec3_t v1, v2; + + VectorSubtract (w->p[1], w->p[0], v1); + VectorSubtract (w->p[2], w->p[0], v2); + CrossProduct (v2, v1, normal); + VectorNormalize (normal, normal); + *dist = DotProduct (w->p[0], normal); + +} + +/* +============= +WindingArea +============= +*/ +vec_t WindingArea (winding_t *w) +{ + int i; + vec3_t d1, d2, cross; + vec_t total; + + total = 0; + for (i=2 ; inumpoints ; i++) + { + VectorSubtract (w->p[i-1], w->p[0], d1); + VectorSubtract (w->p[i], w->p[0], d2); + CrossProduct (d1, d2, cross); + total += 0.5 * VectorLength ( cross ); + } + return total; +} + +void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs) +{ + vec_t v; + int i,j; + + mins[0] = mins[1] = mins[2] = 99999; + maxs[0] = maxs[1] = maxs[2] = -99999; + + for (i=0 ; inumpoints ; i++) + { + for (j=0 ; j<3 ; j++) + { + v = w->p[i][j]; + if (v < mins[j]) + mins[j] = v; + if (v > maxs[j]) + maxs[j] = v; + } + } +} + +/* +============= +WindingCenter +============= +*/ +void WindingCenter (winding_t *w, vec3_t center) +{ + int i; + float scale; + + VectorCopy (vec3_origin, center); + for (i=0 ; inumpoints ; i++) + VectorAdd (w->p[i], center, center); + + scale = 1.0/w->numpoints; + VectorScale (center, scale, center); +} + +/* +================= +BaseWindingForPlane +================= +*/ +winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist) +{ + int i, x; + vec_t max, v; + vec3_t org, vright, vup; + winding_t *w; + +// find the major axis + + max = -BOGUS_RANGE; + x = -1; + for (i=0 ; i<3; i++) + { + v = fabs(normal[i]); + if (v > max) + { + x = i; + max = v; + } + } + if (x==-1) + Error ("BaseWindingForPlane: no axis found"); + + VectorCopy (vec3_origin, vup); + switch (x) + { + case 0: + case 1: + vup[2] = 1; + break; + case 2: + vup[0] = 1; + break; + } + + v = DotProduct (vup, normal); + VectorMA (vup, -v, normal, vup); + VectorNormalize (vup, vup); + + VectorScale (normal, dist, org); + + CrossProduct (vup, normal, vright); + + VectorScale (vup, 8192, vup); + VectorScale (vright, 8192, vright); + +// project a really big axis aligned box onto the plane + w = AllocWinding (4); + + VectorSubtract (org, vright, w->p[0]); + VectorAdd (w->p[0], vup, w->p[0]); + + VectorAdd (org, vright, w->p[1]); + VectorAdd (w->p[1], vup, w->p[1]); + + VectorAdd (org, vright, w->p[2]); + VectorSubtract (w->p[2], vup, w->p[2]); + + VectorSubtract (org, vright, w->p[3]); + VectorSubtract (w->p[3], vup, w->p[3]); + + w->numpoints = 4; + + return w; +} + +/* +================== +CopyWinding +================== +*/ +winding_t *CopyWinding (winding_t *w) +{ + int size; + winding_t *c; + + c = AllocWinding (w->numpoints); + size = (int)((winding_t *)0)->p[w->numpoints]; + memcpy (c, w, size); + return c; +} + +/* +================== +ReverseWinding +================== +*/ +winding_t *ReverseWinding (winding_t *w) +{ + int i; + winding_t *c; + + c = AllocWinding (w->numpoints); + for (i=0 ; inumpoints ; i++) + { + VectorCopy (w->p[w->numpoints-1-i], c->p[i]); + } + c->numpoints = w->numpoints; + return c; +} + + +/* +============= +ClipWindingEpsilon +============= +*/ +void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, + vec_t epsilon, winding_t **front, winding_t **back) +{ + vec_t dists[MAX_POINTS_ON_WINDING+4]; + int sides[MAX_POINTS_ON_WINDING+4]; + int counts[3]; + static vec_t dot; // VC 4.2 optimizer bug if not static + int i, j; + vec_t *p1, *p2; + vec3_t mid; + winding_t *f, *b; + int maxpts; + + counts[0] = counts[1] = counts[2] = 0; + +// determine sides for each point + for (i=0 ; inumpoints ; i++) + { + dot = DotProduct (in->p[i], normal); + dot -= dist; + dists[i] = dot; + if (dot > epsilon) + sides[i] = SIDE_FRONT; + else if (dot < -epsilon) + sides[i] = SIDE_BACK; + else + { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + *front = *back = NULL; + + if (!counts[0]) + { + *back = CopyWinding (in); + return; + } + if (!counts[1]) + { + *front = CopyWinding (in); + return; + } + + maxpts = in->numpoints+4; // cant use counts[0]+2 because + // of fp grouping errors + + *front = f = AllocWinding (maxpts); + *back = b = AllocWinding (maxpts); + + for (i=0 ; inumpoints ; i++) + { + p1 = in->p[i]; + + if (sides[i] == SIDE_ON) + { + VectorCopy (p1, f->p[f->numpoints]); + f->numpoints++; + VectorCopy (p1, b->p[b->numpoints]); + b->numpoints++; + continue; + } + + if (sides[i] == SIDE_FRONT) + { + VectorCopy (p1, f->p[f->numpoints]); + f->numpoints++; + } + if (sides[i] == SIDE_BACK) + { + VectorCopy (p1, b->p[b->numpoints]); + b->numpoints++; + } + + if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + // generate a split point + p2 = in->p[(i+1)%in->numpoints]; + + dot = dists[i] / (dists[i]-dists[i+1]); + for (j=0 ; j<3 ; j++) + { // avoid round off error when possible + if (normal[j] == 1) + mid[j] = dist; + else if (normal[j] == -1) + mid[j] = -dist; + else + mid[j] = p1[j] + dot*(p2[j]-p1[j]); + } + + VectorCopy (mid, f->p[f->numpoints]); + f->numpoints++; + VectorCopy (mid, b->p[b->numpoints]); + b->numpoints++; + } + + if (f->numpoints > maxpts || b->numpoints > maxpts) + Error ("ClipWinding: points exceeded estimate"); + if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING) + Error ("ClipWinding: MAX_POINTS_ON_WINDING"); +} + + +/* +============= +ChopWindingInPlace +============= +*/ +void ChopWindingInPlace (winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon) +{ + winding_t *in; + vec_t dists[MAX_POINTS_ON_WINDING+4]; + int sides[MAX_POINTS_ON_WINDING+4]; + int counts[3]; + static vec_t dot; // VC 4.2 optimizer bug if not static + int i, j; + vec_t *p1, *p2; + vec3_t mid; + winding_t *f; + int maxpts; + + in = *inout; + counts[0] = counts[1] = counts[2] = 0; + +// determine sides for each point + for (i=0 ; inumpoints ; i++) + { + dot = DotProduct (in->p[i], normal); + dot -= dist; + dists[i] = dot; + if (dot > epsilon) + sides[i] = SIDE_FRONT; + else if (dot < -epsilon) + sides[i] = SIDE_BACK; + else + { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + if (!counts[0]) + { + FreeWinding (in); + *inout = NULL; + return; + } + if (!counts[1]) + return; // inout stays the same + + maxpts = in->numpoints+4; // cant use counts[0]+2 because + // of fp grouping errors + + f = AllocWinding (maxpts); + + for (i=0 ; inumpoints ; i++) + { + p1 = in->p[i]; + + if (sides[i] == SIDE_ON) + { + VectorCopy (p1, f->p[f->numpoints]); + f->numpoints++; + continue; + } + + if (sides[i] == SIDE_FRONT) + { + VectorCopy (p1, f->p[f->numpoints]); + f->numpoints++; + } + + if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + // generate a split point + p2 = in->p[(i+1)%in->numpoints]; + + dot = dists[i] / (dists[i]-dists[i+1]); + for (j=0 ; j<3 ; j++) + { // avoid round off error when possible + if (normal[j] == 1) + mid[j] = dist; + else if (normal[j] == -1) + mid[j] = -dist; + else + mid[j] = p1[j] + dot*(p2[j]-p1[j]); + } + + VectorCopy (mid, f->p[f->numpoints]); + f->numpoints++; + } + + if (f->numpoints > maxpts) + Error ("ClipWinding: points exceeded estimate"); + if (f->numpoints > MAX_POINTS_ON_WINDING) + Error ("ClipWinding: MAX_POINTS_ON_WINDING"); + + FreeWinding (in); + *inout = f; +} + + +/* +================= +ChopWinding + +Returns the fragment of in that is on the front side +of the cliping plane. The original is freed. +================= +*/ +winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist) +{ + winding_t *f, *b; + + ClipWindingEpsilon (in, normal, dist, ON_EPSILON, &f, &b); + FreeWinding (in); + if (b) + FreeWinding (b); + return f; +} + + +/* +================= +CheckWinding + +================= +*/ +void CheckWinding (winding_t *w) +{ + int i, j; + vec_t *p1, *p2; + vec_t d, edgedist; + vec3_t dir, edgenormal, facenormal; + vec_t area; + vec_t facedist; + + if (w->numpoints < 3) + Error ("CheckWinding: %i points",w->numpoints); + + area = WindingArea(w); + if (area < 1) + Error ("CheckWinding: %f area", area); + + WindingPlane (w, facenormal, &facedist); + + for (i=0 ; inumpoints ; i++) + { + p1 = w->p[i]; + + for (j=0 ; j<3 ; j++) + if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE) + Error ("CheckFace: BUGUS_RANGE: %f",p1[j]); + + j = i+1 == w->numpoints ? 0 : i+1; + + // check the point is on the face plane + d = DotProduct (p1, facenormal) - facedist; + if (d < -ON_EPSILON || d > ON_EPSILON) + Error ("CheckWinding: point off plane"); + + // check the edge isnt degenerate + p2 = w->p[j]; + VectorSubtract (p2, p1, dir); + + if (VectorLength (dir) < ON_EPSILON) + Error ("CheckWinding: degenerate edge"); + + CrossProduct (facenormal, dir, edgenormal); + VectorNormalize (edgenormal, edgenormal); + edgedist = DotProduct (p1, edgenormal); + edgedist += ON_EPSILON; + + // all other points must be on front side + for (j=0 ; jnumpoints ; j++) + { + if (j == i) + continue; + d = DotProduct (w->p[j], edgenormal); + if (d > edgedist) + Error ("CheckWinding: non-convex"); + } + } +} + + +/* +============ +WindingOnPlaneSide +============ +*/ +int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist) +{ + qboolean front, back; + int i; + vec_t d; + + front = false; + back = false; + for (i=0 ; inumpoints ; i++) + { + d = DotProduct (w->p[i], normal) - dist; + if (d < -ON_EPSILON) + { + if (front) + return SIDE_CROSS; + back = true; + continue; + } + if (d > ON_EPSILON) + { + if (back) + return SIDE_CROSS; + front = true; + continue; + } + } + + if (back) + return SIDE_BACK; + if (front) + return SIDE_FRONT; + return SIDE_ON; +} + diff --git a/tools/quake2/extra/common/polylib.h b/tools/quake2/extra/common/polylib.h new file mode 100644 index 00000000..2024a0dc --- /dev/null +++ b/tools/quake2/extra/common/polylib.h @@ -0,0 +1,55 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +typedef struct +{ + int numpoints; + vec3_t p[4]; // variable sized +} winding_t; + +#define MAX_POINTS_ON_WINDING 64 + +// you can define on_epsilon in the makefile as tighter +#ifndef ON_EPSILON +#define ON_EPSILON 0.1 +#endif + +winding_t *AllocWinding (int points); +vec_t WindingArea (winding_t *w); +void WindingCenter (winding_t *w, vec3_t center); +void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, + vec_t epsilon, winding_t **front, winding_t **back); +winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist); +winding_t *CopyWinding (winding_t *w); +winding_t *ReverseWinding (winding_t *w); +winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist); +void CheckWinding (winding_t *w); +void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist); +void RemoveColinearPoints (winding_t *w); +int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist); +void FreeWinding (winding_t *w); +void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs); + +void ChopWindingInPlace (winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon); +// frees the original if clipped + +void pw(winding_t *w); diff --git a/tools/quake2/extra/common/qfiles.h b/tools/quake2/extra/common/qfiles.h new file mode 100644 index 00000000..d7a85563 --- /dev/null +++ b/tools/quake2/extra/common/qfiles.h @@ -0,0 +1,486 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// +// qfiles.h: quake file formats +// This file must be identical in the quake and utils directories +// + +/* +======================================================================== + +The .pak files are just a linear collapse of a directory tree + +======================================================================== +*/ + +#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P') + +typedef struct +{ + char name[56]; + int filepos, filelen; +} dpackfile_t; + +typedef struct +{ + int ident; // == IDPAKHEADER + int dirofs; + int dirlen; +} dpackheader_t; + +#define MAX_FILES_IN_PACK 4096 + + +/* +======================================================================== + +PCX files are used for as many images as possible + +======================================================================== +*/ + +typedef struct +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned char data; // unbounded +} pcx_t; + + +/* +======================================================================== + +.MD2 triangle model file format + +======================================================================== +*/ + +#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I') +#define ALIAS_VERSION 8 + +#define MAX_TRIANGLES 4096 +#define MAX_VERTS 2048 +#define MAX_FRAMES 512 +#define MAX_MD2SKINS 32 +#define MAX_SKINNAME 64 + +typedef struct +{ + short s; + short t; +} dstvert_t; + +typedef struct +{ + short index_xyz[3]; + short index_st[3]; +} dtriangle_t; + +typedef struct +{ + byte v[3]; // scaled byte to fit in frame mins/maxs + byte lightnormalindex; +} dtrivertx_t; + +#define DTRIVERTX_V0 0 +#define DTRIVERTX_V1 1 +#define DTRIVERTX_V2 2 +#define DTRIVERTX_LNI 3 +#define DTRIVERTX_SIZE 4 + +typedef struct +{ + float scale[3]; // multiply byte verts by this + float translate[3]; // then add this + char name[16]; // frame name from grabbing + dtrivertx_t verts[1]; // variable sized +} daliasframe_t; + + +// the glcmd format: +// a positive integer starts a tristrip command, followed by that many +// vertex structures. +// a negative integer starts a trifan command, followed by -x vertexes +// a zero indicates the end of the command list. +// a vertex consists of a floating point s, a floating point t, +// and an integer vertex index. + + +typedef struct +{ + int ident; + int version; + + int skinwidth; + int skinheight; + int framesize; // byte size of each frame + + int num_skins; + int num_xyz; + int num_st; // greater than num_xyz for seams + int num_tris; + int num_glcmds; // dwords in strip/fan command list + int num_frames; + + int ofs_skins; // each skin is a MAX_SKINNAME string + int ofs_st; // byte offset from start for stverts + int ofs_tris; // offset for dtriangles + int ofs_frames; // offset for first frame + int ofs_glcmds; + int ofs_end; // end of file + +} dmdl_t; + +/* +======================================================================== + +.SP2 sprite file format + +======================================================================== +*/ + +#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I') + // little-endian "IDS2" +#define SPRITE_VERSION 2 + +typedef struct +{ + int width, height; + int origin_x, origin_y; // raster coordinates inside pic + char name[MAX_SKINNAME]; // name of pcx file +} dsprframe_t; + +typedef struct { + int ident; + int version; + int numframes; + dsprframe_t frames[1]; // variable sized +} dsprite_t; + +/* +============================================================================== + + .WAL texture file format + +============================================================================== +*/ + + +#define MIPLEVELS 4 +typedef struct miptex_s +{ + char name[32]; + unsigned width, height; + unsigned offsets[MIPLEVELS]; // four mip maps stored + char animname[32]; // next frame in animation chain + int flags; + int contents; + int value; +} miptex_t; + + + +/* +============================================================================== + + .BSP file format + +============================================================================== +*/ + +#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') + // little-endian "IBSP" + +#define BSPVERSION 38 + + +// upper design bounds +// leaffaces, leafbrushes, planes, and verts are still bounded by +// 16 bit short limits +#define MAX_MAP_MODELS 1024 +#define MAX_MAP_BRUSHES 8192 +#define MAX_MAP_ENTITIES 2048 +#define MAX_MAP_ENTSTRING 0x40000 +#define MAX_MAP_TEXINFO 8192 + +#define MAX_MAP_AREAS 256 +#define MAX_MAP_AREAPORTALS 1024 +#define MAX_MAP_PLANES 65536 +#define MAX_MAP_NODES 65536 +#define MAX_MAP_BRUSHSIDES 65536 +#define MAX_MAP_LEAFS 65536 +#define MAX_MAP_VERTS 65536 +#define MAX_MAP_FACES 65536 +#define MAX_MAP_LEAFFACES 65536 +#define MAX_MAP_LEAFBRUSHES 65536 +#define MAX_MAP_PORTALS 65536 +#define MAX_MAP_EDGES 128000 +#define MAX_MAP_SURFEDGES 256000 +#define MAX_MAP_LIGHTING 0x200000 +#define MAX_MAP_VISIBILITY 0x100000 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + +//============================================================================= + +typedef struct +{ + int fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_PLANES 1 +#define LUMP_VERTEXES 2 +#define LUMP_VISIBILITY 3 +#define LUMP_NODES 4 +#define LUMP_TEXINFO 5 +#define LUMP_FACES 6 +#define LUMP_LIGHTING 7 +#define LUMP_LEAFS 8 +#define LUMP_LEAFFACES 9 +#define LUMP_LEAFBRUSHES 10 +#define LUMP_EDGES 11 +#define LUMP_SURFEDGES 12 +#define LUMP_MODELS 13 +#define LUMP_BRUSHES 14 +#define LUMP_BRUSHSIDES 15 +#define LUMP_POP 16 +#define LUMP_AREAS 17 +#define LUMP_AREAPORTALS 18 +#define HEADER_LUMPS 19 + +typedef struct +{ + int ident; + int version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; // for sounds or lights + int headnode; + int firstface, numfaces; // submodels just draw faces + // without walking the bsp tree +} dmodel_t; + + +typedef struct +{ + float point[3]; +} dvertex_t; + + +// 0-2 are axial planes +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +// 3-5 are non-axial planes snapped to the nearest +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +// planes (x&~1) and (x&~1)+1 are allways opposites + +typedef struct +{ + float normal[3]; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + + +// contents flags are seperate bits +// a given brush can contribute multiple content bits +// multiple brushes can be in a single leaf + +// these definitions also need to be in q_shared.h! + +// lower bits are stronger, and will eat weaker brushes completely +#define CONTENTS_SOLID 1 // an eye is never valid in a solid +#define CONTENTS_WINDOW 2 // translucent, but not watery +#define CONTENTS_AUX 4 +#define CONTENTS_LAVA 8 +#define CONTENTS_SLIME 16 +#define CONTENTS_WATER 32 +#define CONTENTS_MIST 64 +#define LAST_VISIBLE_CONTENTS 64 + +// remaining contents are non-visible, and don't eat brushes + +#define CONTENTS_AREAPORTAL 0x8000 + +#define CONTENTS_PLAYERCLIP 0x10000 +#define CONTENTS_MONSTERCLIP 0x20000 + +// currents can be added to any other contents, and may be mixed +#define CONTENTS_CURRENT_0 0x40000 +#define CONTENTS_CURRENT_90 0x80000 +#define CONTENTS_CURRENT_180 0x100000 +#define CONTENTS_CURRENT_270 0x200000 +#define CONTENTS_CURRENT_UP 0x400000 +#define CONTENTS_CURRENT_DOWN 0x800000 + +#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity + +#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game +#define CONTENTS_DEADMONSTER 0x4000000 +#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs +#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans +#define CONTENTS_LADDER 0x20000000 + + + +#define SURF_LIGHT 0x1 // value will hold the light strength + +#define SURF_SLICK 0x2 // effects game physics + +#define SURF_SKY 0x4 // don't draw, but add to skybox +#define SURF_WARP 0x8 // turbulent water warp +#define SURF_TRANS33 0x10 +#define SURF_TRANS66 0x20 +#define SURF_FLOWING 0x40 // scroll towards angle +#define SURF_NODRAW 0x80 // don't bother referencing the texture + +#define SURF_HINT 0x100 // make a primary bsp splitter +#define SURF_SKIP 0x200 // completely ignore, allowing non-closed brushes + + + +typedef struct +{ + int planenum; + int children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for frustom culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides +} dnode_t; + + +typedef struct texinfo_s +{ + float vecs[2][4]; // [s/t][xyz offset] + int flags; // miptex flags + overrides + int value; // light emission, etc + char texture[32]; // texture name (textures/*.wal) + int nexttexinfo; // for animations, -1 = end of chain +} texinfo_t; + + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +typedef struct +{ + unsigned short v[2]; // vertex numbers +} dedge_t; + +#define MAXLIGHTMAPS 4 +typedef struct +{ + unsigned short planenum; + short side; + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dface_t; + +typedef struct +{ + int contents; // OR of all brushes (not needed?) + + short cluster; + short area; + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstleafface; + unsigned short numleaffaces; + + unsigned short firstleafbrush; + unsigned short numleafbrushes; +} dleaf_t; + +typedef struct +{ + unsigned short planenum; // facing out of the leaf + short texinfo; +} dbrushside_t; + +typedef struct +{ + int firstside; + int numsides; + int contents; +} dbrush_t; + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +// the visibility lump consists of a header with a count, then +// byte offsets for the PVS and PHS of each cluster, then the raw +// compressed bit vectors +#define DVIS_PVS 0 +#define DVIS_PHS 1 +typedef struct +{ + int numclusters; + int bitofs[8][2]; // bitofs[numclusters][2] +} dvis_t; + +// each area has a list of portals that lead into other areas +// when portals are closed, other areas may not be visible or +// hearable even if the vis info says that it should be +typedef struct +{ + int portalnum; + int otherarea; +} dareaportal_t; + +typedef struct +{ + int numareaportals; + int firstareaportal; +} darea_t; diff --git a/tools/quake2/extra/common/scriplib.c b/tools/quake2/extra/common/scriplib.c new file mode 100644 index 00000000..a9e2f3b5 --- /dev/null +++ b/tools/quake2/extra/common/scriplib.c @@ -0,0 +1,297 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// scriplib.c + +#include "cmdlib.h" +#include "scriplib.h" + +/* +============================================================================= + + PARSING STUFF + +============================================================================= +*/ + +typedef struct +{ + char filename[1024]; + char *buffer,*script_p,*end_p; + int line; +} script_t; + +#define MAX_INCLUDES 8 +script_t scriptstack[MAX_INCLUDES]; +script_t *script; +int scriptline; + +char token[MAXTOKEN]; +qboolean endofscript; +qboolean tokenready; // only true if UnGetToken was just called + +/* +============== +AddScriptToStack +============== +*/ +void AddScriptToStack (char *filename) +{ + int size; + + script++; + if (script == &scriptstack[MAX_INCLUDES]) + Error ("script file exceeded MAX_INCLUDES"); + strcpy (script->filename, ExpandPath (filename) ); + + size = LoadFile (script->filename, (void **)&script->buffer); + + printf ("entering %s\n", script->filename); + + script->line = 1; + + script->script_p = script->buffer; + script->end_p = script->buffer + size; +} + + +/* +============== +LoadScriptFile +============== +*/ +void LoadScriptFile (char *filename) +{ + script = scriptstack; + AddScriptToStack (filename); + + endofscript = false; + tokenready = false; +} + + +/* +============== +ParseFromMemory +============== +*/ +void ParseFromMemory (char *buffer, int size) +{ + script = scriptstack; + script++; + if (script == &scriptstack[MAX_INCLUDES]) + Error ("script file exceeded MAX_INCLUDES"); + strcpy (script->filename, "memory buffer" ); + + script->buffer = buffer; + script->line = 1; + script->script_p = script->buffer; + script->end_p = script->buffer + size; + + endofscript = false; + tokenready = false; +} + + +/* +============== +UnGetToken + +Signals that the current token was not used, and should be reported +for the next GetToken. Note that + +GetToken (true); +UnGetToken (); +GetToken (false); + +could cross a line boundary. +============== +*/ +void UnGetToken (void) +{ + tokenready = true; +} + + +qboolean EndOfScript (qboolean crossline) +{ + if (!crossline) + Error ("Line %i is incomplete\n",scriptline); + + if (!strcmp (script->filename, "memory buffer")) + { + endofscript = true; + return false; + } + + free (script->buffer); + if (script == scriptstack+1) + { + endofscript = true; + return false; + } + script--; + scriptline = script->line; + printf ("returning to %s\n", script->filename); + return GetToken (crossline); +} + +/* +============== +GetToken +============== +*/ +qboolean GetToken (qboolean crossline) +{ + char *token_p; + + if (tokenready) // is a token allready waiting? + { + tokenready = false; + return true; + } + + if (script->script_p >= script->end_p) + return EndOfScript (crossline); + +// +// skip space +// +skipspace: + while (*script->script_p <= 32) + { + if (script->script_p >= script->end_p) + return EndOfScript (crossline); + if (*script->script_p++ == '\n') + { + if (!crossline) + Error ("Line %i is incomplete\n",scriptline); + scriptline = script->line++; + } + } + + if (script->script_p >= script->end_p) + return EndOfScript (crossline); + + // ; # // comments + if (*script->script_p == ';' || *script->script_p == '#' + || ( script->script_p[0] == '/' && script->script_p[1] == '/') ) + { + if (!crossline) + Error ("Line %i is incomplete\n",scriptline); + while (*script->script_p++ != '\n') + if (script->script_p >= script->end_p) + return EndOfScript (crossline); + goto skipspace; + } + + // /* */ comments + if (script->script_p[0] == '/' && script->script_p[1] == '*') + { + if (!crossline) + Error ("Line %i is incomplete\n",scriptline); + script->script_p+=2; + while (script->script_p[0] != '*' && script->script_p[1] != '/') + { + script->script_p++; + if (script->script_p >= script->end_p) + return EndOfScript (crossline); + } + script->script_p += 2; + goto skipspace; + } + +// +// copy token +// + token_p = token; + + if (*script->script_p == '"') + { + // quoted token + script->script_p++; + while (*script->script_p != '"') + { + *token_p++ = *script->script_p++; + if (script->script_p == script->end_p) + break; + if (token_p == &token[MAXTOKEN]) + Error ("Token too large on line %i\n",scriptline); + } + script->script_p++; + } + else // regular token + while ( *script->script_p > 32 && *script->script_p != ';') + { + *token_p++ = *script->script_p++; + if (script->script_p == script->end_p) + break; + if (token_p == &token[MAXTOKEN]) + Error ("Token too large on line %i\n",scriptline); + } + + *token_p = 0; + + if (!strcmp (token, "$include")) + { + GetToken (false); + AddScriptToStack (token); + return GetToken (crossline); + } + + return true; +} + + +/* +============== +TokenAvailable + +Returns true if there is another token on the line +============== +*/ +qboolean TokenAvailable (void) +{ + char *search_p; + + search_p = script->script_p; + + if (search_p >= script->end_p) + return false; + + while ( *search_p <= 32) + { + if (*search_p == '\n') + return false; + search_p++; + if (search_p == script->end_p) + return false; + + } + + if (*search_p == ';') + return false; + + return true; +} + + diff --git a/tools/quake2/extra/common/scriplib.h b/tools/quake2/extra/common/scriplib.h new file mode 100644 index 00000000..25c1c059 --- /dev/null +++ b/tools/quake2/extra/common/scriplib.h @@ -0,0 +1,45 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// scriplib.h + +#ifndef __CMDLIB__ +#include "cmdlib.h" +#endif + +#define MAXTOKEN 1024 + +extern char token[MAXTOKEN]; +extern char *scriptbuffer,*script_p,*scriptend_p; +extern int grabbed; +extern int scriptline; +extern qboolean endofscript; + + +void LoadScriptFile (char *filename); +void ParseFromMemory (char *buffer, int size); + +qboolean GetToken (qboolean crossline); +void UnGetToken (void); +qboolean TokenAvailable (void); + + diff --git a/tools/quake2/extra/common/threads.c b/tools/quake2/extra/common/threads.c new file mode 100644 index 00000000..25a87c78 --- /dev/null +++ b/tools/quake2/extra/common/threads.c @@ -0,0 +1,448 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "cmdlib.h" +#include "threads.h" + +#define MAX_THREADS 64 + +int dispatch; +int workcount; +int oldf; +qboolean pacifier; + +qboolean threaded; + +/* +============= +GetThreadWork + +============= +*/ +int GetThreadWork (void) +{ + int r; + int f; + + ThreadLock (); + + if (dispatch == workcount) + { + ThreadUnlock (); + return -1; + } + + f = 10*dispatch / workcount; + if (f != oldf) + { + oldf = f; + if (pacifier) + printf ("%i...", f); + } + + r = dispatch; + dispatch++; + ThreadUnlock (); + + return r; +} + + +void (*workfunction) (int); + +void ThreadWorkerFunction (int threadnum) +{ + int work; + + while (1) + { + work = GetThreadWork (); + if (work == -1) + break; +//printf ("thread %i, work %i\n", threadnum, work); + workfunction(work); + } +} + +void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int)) +{ + if (numthreads == -1) + ThreadSetDefault (); + workfunction = func; + RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction); +} + + +/* +=================================================================== + +WIN32 + +=================================================================== +*/ +#ifdef WIN32 + +#define USED + +#include + +int numthreads = -1; +CRITICAL_SECTION crit; +static int enter; + +void ThreadSetDefault (void) +{ + SYSTEM_INFO info; + + if (numthreads == -1) // not set manually + { + GetSystemInfo (&info); + numthreads = info.dwNumberOfProcessors; + if (numthreads < 1 || numthreads > 32) + numthreads = 1; + } + + qprintf ("%i threads\n", numthreads); +} + + +void ThreadLock (void) +{ + if (!threaded) + return; + EnterCriticalSection (&crit); + if (enter) + Error ("Recursive ThreadLock\n"); + enter = 1; +} + +void ThreadUnlock (void) +{ + if (!threaded) + return; + if (!enter) + Error ("ThreadUnlock without lock\n"); + enter = 0; + LeaveCriticalSection (&crit); +} + +/* +============= +RunThreadsOn +============= +*/ +void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int)) +{ + int threadid[MAX_THREADS]; + HANDLE threadhandle[MAX_THREADS]; + int i; + int start, end; + + start = I_FloatTime (); + dispatch = 0; + workcount = workcnt; + oldf = -1; + pacifier = showpacifier; + threaded = true; + + // + // run threads in parallel + // + InitializeCriticalSection (&crit); + + if (numthreads == 1) + { // use same thread + func (0); + } + else + { + for (i=0 ; i + +pthread_mutex_t *my_mutex; + +void ThreadLock (void) +{ + if (my_mutex) + pthread_mutex_lock (my_mutex); +} + +void ThreadUnlock (void) +{ + if (my_mutex) + pthread_mutex_unlock (my_mutex); +} + + +/* +============= +RunThreadsOn +============= +*/ +void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int)) +{ + int i; + pthread_t work_threads[MAX_THREADS]; + pthread_addr_t status; + pthread_attr_t attrib; + pthread_mutexattr_t mattrib; + int start, end; + + start = I_FloatTime (); + dispatch = 0; + workcount = workcnt; + oldf = -1; + pacifier = showpacifier; + threaded = true; + + if (pacifier) + setbuf (stdout, NULL); + + if (!my_mutex) + { + my_mutex = malloc (sizeof(*my_mutex)); + if (pthread_mutexattr_create (&mattrib) == -1) + Error ("pthread_mutex_attr_create failed"); + if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1) + Error ("pthread_mutexattr_setkind_np failed"); + if (pthread_mutex_init (my_mutex, mattrib) == -1) + Error ("pthread_mutex_init failed"); + } + + if (pthread_attr_create (&attrib) == -1) + Error ("pthread_attr_create failed"); + if (pthread_attr_setstacksize (&attrib, 0x100000) == -1) + Error ("pthread_attr_setstacksize failed"); + + for (i=0 ; i +#include +#include +#include + + +int numthreads = -1; +abilock_t lck; + +void ThreadSetDefault (void) +{ + if (numthreads == -1) + numthreads = prctl(PR_MAXPPROCS); + printf ("%i threads\n", numthreads); +//@@ + usconfig (CONF_INITUSERS, numthreads); +} + + +void ThreadLock (void) +{ + spin_lock (&lck); +} + +void ThreadUnlock (void) +{ + release_lock (&lck); +} + + +/* +============= +RunThreadsOn +============= +*/ +void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int)) +{ + int i; + int pid[MAX_THREADS]; + int start, end; + + start = I_FloatTime (); + dispatch = 0; + workcount = workcnt; + oldf = -1; + pacifier = showpacifier; + threaded = true; + + if (pacifier) + setbuf (stdout, NULL); + + init_lock (&lck); + + for (i=0 ; i +#include "cmdlib.h" +#include "mathlib.h" +#include "trilib.h" + +// on disk representation of a face + + +#define FLOAT_START 99999.0 +#define FLOAT_END -FLOAT_START +#define MAGIC 123322 + +//#define NOISY 1 + +typedef struct { + float v[3]; +} vector; + +typedef struct +{ + vector n; /* normal */ + vector p; /* point */ + vector c; /* color */ + float u; /* u */ + float v; /* v */ +} aliaspoint_t; + +typedef struct { + aliaspoint_t pt[3]; +} tf_triangle; + + +void ByteSwapTri (tf_triangle *tri) +{ + int i; + + for (i=0 ; iverts[j][k] = tri.pt[j].p.v[k]; + } + } + + ptri++; + + if ((ptri - *pptri) >= MAXTRIANGLES) + Error ("Error: too many triangles; increase MAXTRIANGLES\n"); + } + } + + *numtriangles = ptri - *pptri; + + fclose (input); +} + diff --git a/tools/quake2/extra/common/trilib.h b/tools/quake2/extra/common/trilib.h new file mode 100644 index 00000000..11ece3de --- /dev/null +++ b/tools/quake2/extra/common/trilib.h @@ -0,0 +1,33 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// +// trilib.h: header file for loading triangles from an Alias triangle file +// +#define MAXTRIANGLES 2048 + +typedef struct { + vec3_t verts[3]; +} triangle_t; + +void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles); + diff --git a/tools/quake2/extra/qdata/anorms.h b/tools/quake2/extra/qdata/anorms.h new file mode 100644 index 00000000..18da0abc --- /dev/null +++ b/tools/quake2/extra/qdata/anorms.h @@ -0,0 +1,184 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +{-0.525731, 0.000000, 0.850651}, +{-0.442863, 0.238856, 0.864188}, +{-0.295242, 0.000000, 0.955423}, +{-0.309017, 0.500000, 0.809017}, +{-0.162460, 0.262866, 0.951056}, +{0.000000, 0.000000, 1.000000}, +{0.000000, 0.850651, 0.525731}, +{-0.147621, 0.716567, 0.681718}, +{0.147621, 0.716567, 0.681718}, +{0.000000, 0.525731, 0.850651}, +{0.309017, 0.500000, 0.809017}, +{0.525731, 0.000000, 0.850651}, +{0.295242, 0.000000, 0.955423}, +{0.442863, 0.238856, 0.864188}, +{0.162460, 0.262866, 0.951056}, +{-0.681718, 0.147621, 0.716567}, +{-0.809017, 0.309017, 0.500000}, +{-0.587785, 0.425325, 0.688191}, +{-0.850651, 0.525731, 0.000000}, +{-0.864188, 0.442863, 0.238856}, +{-0.716567, 0.681718, 0.147621}, +{-0.688191, 0.587785, 0.425325}, +{-0.500000, 0.809017, 0.309017}, +{-0.238856, 0.864188, 0.442863}, +{-0.425325, 0.688191, 0.587785}, +{-0.716567, 0.681718, -0.147621}, +{-0.500000, 0.809017, -0.309017}, +{-0.525731, 0.850651, 0.000000}, +{0.000000, 0.850651, -0.525731}, +{-0.238856, 0.864188, -0.442863}, +{0.000000, 0.955423, -0.295242}, +{-0.262866, 0.951056, -0.162460}, +{0.000000, 1.000000, 0.000000}, +{0.000000, 0.955423, 0.295242}, +{-0.262866, 0.951056, 0.162460}, +{0.238856, 0.864188, 0.442863}, +{0.262866, 0.951056, 0.162460}, +{0.500000, 0.809017, 0.309017}, +{0.238856, 0.864188, -0.442863}, +{0.262866, 0.951056, -0.162460}, +{0.500000, 0.809017, -0.309017}, +{0.850651, 0.525731, 0.000000}, +{0.716567, 0.681718, 0.147621}, +{0.716567, 0.681718, -0.147621}, +{0.525731, 0.850651, 0.000000}, +{0.425325, 0.688191, 0.587785}, +{0.864188, 0.442863, 0.238856}, +{0.688191, 0.587785, 0.425325}, +{0.809017, 0.309017, 0.500000}, +{0.681718, 0.147621, 0.716567}, +{0.587785, 0.425325, 0.688191}, +{0.955423, 0.295242, 0.000000}, +{1.000000, 0.000000, 0.000000}, +{0.951056, 0.162460, 0.262866}, +{0.850651, -0.525731, 0.000000}, +{0.955423, -0.295242, 0.000000}, +{0.864188, -0.442863, 0.238856}, +{0.951056, -0.162460, 0.262866}, +{0.809017, -0.309017, 0.500000}, +{0.681718, -0.147621, 0.716567}, +{0.850651, 0.000000, 0.525731}, +{0.864188, 0.442863, -0.238856}, +{0.809017, 0.309017, -0.500000}, +{0.951056, 0.162460, -0.262866}, +{0.525731, 0.000000, -0.850651}, +{0.681718, 0.147621, -0.716567}, +{0.681718, -0.147621, -0.716567}, +{0.850651, 0.000000, -0.525731}, +{0.809017, -0.309017, -0.500000}, +{0.864188, -0.442863, -0.238856}, +{0.951056, -0.162460, -0.262866}, +{0.147621, 0.716567, -0.681718}, +{0.309017, 0.500000, -0.809017}, +{0.425325, 0.688191, -0.587785}, +{0.442863, 0.238856, -0.864188}, +{0.587785, 0.425325, -0.688191}, +{0.688191, 0.587785, -0.425325}, +{-0.147621, 0.716567, -0.681718}, +{-0.309017, 0.500000, -0.809017}, +{0.000000, 0.525731, -0.850651}, +{-0.525731, 0.000000, -0.850651}, +{-0.442863, 0.238856, -0.864188}, +{-0.295242, 0.000000, -0.955423}, +{-0.162460, 0.262866, -0.951056}, +{0.000000, 0.000000, -1.000000}, +{0.295242, 0.000000, -0.955423}, +{0.162460, 0.262866, -0.951056}, +{-0.442863, -0.238856, -0.864188}, +{-0.309017, -0.500000, -0.809017}, +{-0.162460, -0.262866, -0.951056}, +{0.000000, -0.850651, -0.525731}, +{-0.147621, -0.716567, -0.681718}, +{0.147621, -0.716567, -0.681718}, +{0.000000, -0.525731, -0.850651}, +{0.309017, -0.500000, -0.809017}, +{0.442863, -0.238856, -0.864188}, +{0.162460, -0.262866, -0.951056}, +{0.238856, -0.864188, -0.442863}, +{0.500000, -0.809017, -0.309017}, +{0.425325, -0.688191, -0.587785}, +{0.716567, -0.681718, -0.147621}, +{0.688191, -0.587785, -0.425325}, +{0.587785, -0.425325, -0.688191}, +{0.000000, -0.955423, -0.295242}, +{0.000000, -1.000000, 0.000000}, +{0.262866, -0.951056, -0.162460}, +{0.000000, -0.850651, 0.525731}, +{0.000000, -0.955423, 0.295242}, +{0.238856, -0.864188, 0.442863}, +{0.262866, -0.951056, 0.162460}, +{0.500000, -0.809017, 0.309017}, +{0.716567, -0.681718, 0.147621}, +{0.525731, -0.850651, 0.000000}, +{-0.238856, -0.864188, -0.442863}, +{-0.500000, -0.809017, -0.309017}, +{-0.262866, -0.951056, -0.162460}, +{-0.850651, -0.525731, 0.000000}, +{-0.716567, -0.681718, -0.147621}, +{-0.716567, -0.681718, 0.147621}, +{-0.525731, -0.850651, 0.000000}, +{-0.500000, -0.809017, 0.309017}, +{-0.238856, -0.864188, 0.442863}, +{-0.262866, -0.951056, 0.162460}, +{-0.864188, -0.442863, 0.238856}, +{-0.809017, -0.309017, 0.500000}, +{-0.688191, -0.587785, 0.425325}, +{-0.681718, -0.147621, 0.716567}, +{-0.442863, -0.238856, 0.864188}, +{-0.587785, -0.425325, 0.688191}, +{-0.309017, -0.500000, 0.809017}, +{-0.147621, -0.716567, 0.681718}, +{-0.425325, -0.688191, 0.587785}, +{-0.162460, -0.262866, 0.951056}, +{0.442863, -0.238856, 0.864188}, +{0.162460, -0.262866, 0.951056}, +{0.309017, -0.500000, 0.809017}, +{0.147621, -0.716567, 0.681718}, +{0.000000, -0.525731, 0.850651}, +{0.425325, -0.688191, 0.587785}, +{0.587785, -0.425325, 0.688191}, +{0.688191, -0.587785, 0.425325}, +{-0.955423, 0.295242, 0.000000}, +{-0.951056, 0.162460, 0.262866}, +{-1.000000, 0.000000, 0.000000}, +{-0.850651, 0.000000, 0.525731}, +{-0.955423, -0.295242, 0.000000}, +{-0.951056, -0.162460, 0.262866}, +{-0.864188, 0.442863, -0.238856}, +{-0.951056, 0.162460, -0.262866}, +{-0.809017, 0.309017, -0.500000}, +{-0.864188, -0.442863, -0.238856}, +{-0.951056, -0.162460, -0.262866}, +{-0.809017, -0.309017, -0.500000}, +{-0.681718, 0.147621, -0.716567}, +{-0.681718, -0.147621, -0.716567}, +{-0.850651, 0.000000, -0.525731}, +{-0.688191, 0.587785, -0.425325}, +{-0.587785, 0.425325, -0.688191}, +{-0.425325, 0.688191, -0.587785}, +{-0.425325, -0.688191, -0.587785}, +{-0.587785, -0.425325, -0.688191}, +{-0.688191, -0.587785, -0.425325}, diff --git a/tools/quake2/extra/qdata/images.c b/tools/quake2/extra/qdata/images.c new file mode 100644 index 00000000..90934f13 --- /dev/null +++ b/tools/quake2/extra/qdata/images.c @@ -0,0 +1,763 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qdata.h" + +char mip_prefix[1024]; // directory to dump the textures in + +qboolean colormap_issued; +byte colormap_palette[768]; + +/* +============== +RemapZero + +Replaces all 0 bytes in an image with the closest palette entry. +This is because NT won't let us change index 0, so any palette +animation leaves those pixels untouched. +============== +*/ +void RemapZero (byte *pixels, byte *palette, int width, int height) +{ + int i, c; + int alt_zero; + int value, best; + + alt_zero = 0; + best = 9999999; + for (i=1 ; i<255 ; i++) + { + value = palette[i*3+0]+palette[i*3+1]+palette[i*3+2]; + if (value < best) + { + best = value; + alt_zero = i; + } + } + + c = width*height; + for (i=0 ; ibyteimagewidth || yl+h>byteimageheight) + Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h); + + // crop it to the proper size + cropped = malloc (w*h); + for (y=0 ; ybyteimagewidth || yl+h>byteimageheight) + Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h); + + // crop it to the proper size + cropped = malloc (w*h); + for (y=0 ; y 255) + r = 255; + if (r < 0) + r = 0; + if (g > 255) + g = 255; + if (g < 0) + g = 0; + if (b > 255) + b = 255; + if (b < 0) + b = 0; +#ifndef TABLECOLORS + bestcolor = BestColor (r, g, b, 0, 254); +#else + bestcolor = palmap[r>>3][g>>3][b>>3]; +#endif + + return bestcolor; +} + + +void BuildPalmap (void) +{ +#ifdef TABLECOLORS + int r, g, b; + int bestcolor; + + if (palmap_built) + return; + palmap_built = true; + + for (r=4 ; r<256 ; r+=8) + { + for (g=4 ; g<256 ; g+=8) + { + for (b=4 ; b<256 ; b+=8) + { + bestcolor = BestColor (r, g, b, 1, 254); + palmap[r>>3][g>>3][b>>3] = bestcolor; + } + } + } +#endif + + if (!colormap_issued) + Error ("You must issue a $colormap command first"); + +} + +/* +============= +AveragePixels +============= +*/ +byte AveragePixels (int count) +{ + int r,g,b; + int i; + int vis; + int pix; + int bestcolor; + byte *pal; + int fullbright; + + vis = 0; + r = g = b = 0; + fullbright = 0; + for (i=0 ; i +must be multiples of sixteen +SURF_WINDOW +============== +*/ +void Cmd_Mip (void) +{ + int x,y,xl,yl,xh,yh,w,h; + byte *screen_p, *source; + int linedelta; + miptex_t *qtex; + int miplevel, mipstep; + int xx, yy, pix; + int count; + int flags, value, contents; + mipparm_t *mp; + char lumpname[64]; + byte *lump_p; + char filename[1024]; + char animname[64]; + + GetToken (false); + strcpy (lumpname, token); + + GetToken (false); + xl = atoi (token); + GetToken (false); + yl = atoi (token); + GetToken (false); + w = atoi (token); + GetToken (false); + h = atoi (token); + + if ( (w & 15) || (h & 15) ) + Error ("line %i: miptex sizes must be multiples of 16", scriptline); + + flags = 0; + contents = 0; + value = 0; + + animname[0] = 0; + + // get optional flags and values + while (TokenAvailable ()) + { + GetToken (false); + + for (mp=mipparms ; mp->name ; mp++) + { + if (!strcmp(mp->name, token)) + { + switch (mp->type) + { + case pt_animvalue: + GetToken (false); // specify the next animation frame + strcpy (animname, token); + break; + case pt_flags: + flags |= mp->flags; + break; + case pt_contents: + contents |= mp->flags; + break; + case pt_flagvalue: + flags |= mp->flags; + GetToken (false); // specify the light value + value = atoi(token); + break; + } + break; + } + } + if (!mp->name) + Error ("line %i: unknown parm %s", scriptline, token); + } + + sprintf (filename, "%stextures/%s/%s.wal", gamedir, mip_prefix, lumpname); + if (g_release) + return; // textures are only released by $maps + + xh = xl+w; + yh = yl+h; + + qtex = malloc (sizeof(miptex_t) + w*h*2); + memset (qtex, 0, sizeof(miptex_t)); + + qtex->width = LittleLong(w); + qtex->height = LittleLong(h); + qtex->flags = LittleLong(flags); + qtex->contents = LittleLong(contents); + qtex->value = LittleLong(value); + sprintf (qtex->name, "%s/%s", mip_prefix, lumpname); + if (animname[0]) + sprintf (qtex->animname, "%s/%s", mip_prefix, animname); + + lump_p = (byte *)(&qtex->value+1); + + screen_p = byteimage + yl*byteimagewidth + xl; + linedelta = byteimagewidth - w; + + source = lump_p; + qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex); + + for (y=yl ; yoffsets[miplevel] = LittleLong(lump_p - (byte *)qtex); + + mipstep = 1< /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/models.o : models.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/sprites.o : sprites.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/images.o : images.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/tables.o : tables.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i + +$(ODIR)/cmdlib.o : ../common/cmdlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/scriplib.o : ../common/scriplib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/lbmlib.o : ../common/lbmlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/mathlib.o : ../common/mathlib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/trilib.o : ../common/trilib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/l3dslib.o : ../common/l3dslib.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i +$(ODIR)/threads.o : ../common/threads.c + cc $(CFLAGS) -E $? | tr -d '\015' > /tmp/temp.i + cc $(CFLAGS) -o $@ /tmp/temp.i diff --git a/tools/quake2/extra/qdata/models.c b/tools/quake2/extra/qdata/models.c new file mode 100644 index 00000000..d6922cb7 --- /dev/null +++ b/tools/quake2/extra/qdata/models.c @@ -0,0 +1,1152 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qdata.h" + +//================================================================= + +typedef struct +{ + int numnormals; + vec3_t normalsum; +} vertexnormals_t; + +typedef struct +{ + vec3_t v; + int lightnormalindex; +} trivert_t; + +typedef struct +{ + vec3_t mins, maxs; + char name[16]; + trivert_t v[MAX_VERTS]; +} frame_t; + +//================================================================ + +frame_t g_frames[MAX_FRAMES]; + +dmdl_t model; + + +float scale_up; // set by $scale +vec3_t adjust; // set by $origin +int g_fixedwidth, g_fixedheight; // set by $skinsize + + +// +// base frame info +// +vec3_t base_xyz[MAX_VERTS]; +dstvert_t base_st[MAX_VERTS]; +dtriangle_t triangles[MAX_TRIANGLES]; + +int triangle_st[MAX_TRIANGLES][3][2]; + +// the command list holds counts, s/t values, and xyz indexes +// that are valid for every frame +int commands[16384]; +int numcommands; +int numglverts; +int used[MAX_TRIANGLES]; + +char g_skins[MAX_MD2SKINS][64]; + +char cdarchive[1024]; +char cdpartial[1024]; +char cddir[1024]; + +char modelname[64]; // empty unless $modelname issued (players) + +#define NUMVERTEXNORMALS 162 + +float avertexnormals[NUMVERTEXNORMALS][3] = { +#include "anorms.h" +}; + +FILE *headerouthandle = NULL; + +//============================================================== + +/* +=============== +ClearModel +=============== +*/ +void ClearModel (void) +{ + memset (&model, 0, sizeof(model)); + + modelname[0] = 0; + scale_up = 1.0; + VectorCopy (vec3_origin, adjust); + g_fixedwidth = g_fixedheight = 0; + g_skipmodel = false; +} + + +void H_printf(char *fmt, ...) +{ + va_list argptr; + char name[1024]; + + if (!headerouthandle) + { + sprintf (name, "%s/tris.h", cddir); + headerouthandle = SafeOpenWrite (name); + fprintf(headerouthandle, "// %s\n\n", cddir); + fprintf(headerouthandle, "// This file generated by qdata - Do NOT Modify\n\n"); + } + + va_start (argptr, fmt); + vfprintf (headerouthandle, fmt, argptr); + va_end (argptr); +} + + +/* +============ +WriteModelFile +============ +*/ +void WriteModelFile (FILE *modelouthandle) +{ + int i; + dmdl_t modeltemp; + int j, k; + frame_t *in; + daliasframe_t *out; + byte buffer[MAX_VERTS*4+128]; + float v; + int c_on, c_off; + + model.ident = IDALIASHEADER; + model.version = ALIAS_VERSION; + model.framesize = (int)&((daliasframe_t *)0)->verts[model.num_xyz]; + model.num_glcmds = numcommands; + model.ofs_skins = sizeof(dmdl_t); + model.ofs_st = model.ofs_skins + model.num_skins * MAX_SKINNAME; + model.ofs_tris = model.ofs_st + model.num_st*sizeof(dstvert_t); + model.ofs_frames = model.ofs_tris + model.num_tris*sizeof(dtriangle_t); + model.ofs_glcmds = model.ofs_frames + model.num_frames*model.framesize; + model.ofs_end = model.ofs_glcmds + model.num_glcmds*4; + + // + // write out the model header + // + for (i=0 ; iname, in->name); + for (j=0 ; j<3 ; j++) + { + out->scale[j] = (in->maxs[j] - in->mins[j])/255; + out->translate[j] = in->mins[j]; + } + + for (j=0 ; jverts[j].lightnormalindex = in->v[j].lightnormalindex; + + for (k=0 ; k<3 ; k++) + { + // scale to byte values & min/max check + v = Q_rint ( (in->v[j].v[k] - out->translate[k]) / out->scale[k] ); + + // clamp, so rounding doesn't wrap from 255.6 to 0 + if (v > 255.0) + v = 255.0; + if (v < 0) + v = 0; + out->verts[j].v[k] = v; + } + } + + for (j=0 ; j<3 ; j++) + { + out->scale[j] = LittleFloat (out->scale[j]); + out->translate[j] = LittleFloat (out->translate[j]); + } + + SafeWrite (modelouthandle, out, model.framesize); + } + + // + // write out glcmds + // + SafeWrite (modelouthandle, commands, numcommands*4); +} + + +/* +=============== +FinishModel +=============== +*/ +void FinishModel (void) +{ + FILE *modelouthandle; + int i; + char name[1024]; + + if (!model.num_frames) + return; + +// +// copy to release directory tree if doing a release build +// + if (g_release) + { + if (modelname[0]) + sprintf (name, "%s", modelname); + else + sprintf (name, "%s/tris.md2", cdpartial); + ReleaseFile (name); + + for (i=0 ; iindex_xyz[(startv)%3]; + strip_xyz[1] = last->index_xyz[(startv+1)%3]; + strip_xyz[2] = last->index_xyz[(startv+2)%3]; + strip_st[0] = last->index_st[(startv)%3]; + strip_st[1] = last->index_st[(startv+1)%3]; + strip_st[2] = last->index_st[(startv+2)%3]; + + strip_tris[0] = starttri; + stripcount = 1; + + m1 = last->index_xyz[(startv+2)%3]; + st1 = last->index_st[(startv+2)%3]; + m2 = last->index_xyz[(startv+1)%3]; + st2 = last->index_st[(startv+1)%3]; + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] + ; jindex_xyz[k] != m1) + continue; + if (check->index_st[k] != st1) + continue; + if (check->index_xyz[ (k+1)%3 ] != m2) + continue; + if (check->index_st[ (k+1)%3 ] != st2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + if (stripcount & 1) + { + m2 = check->index_xyz[ (k+2)%3 ]; + st2 = check->index_st[ (k+2)%3 ]; + } + else + { + m1 = check->index_xyz[ (k+2)%3 ]; + st1 = check->index_st[ (k+2)%3 ]; + } + + strip_xyz[stripcount+2] = check->index_xyz[ (k+2)%3 ]; + strip_st[stripcount+2] = check->index_st[ (k+2)%3 ]; + strip_tris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; jindex_xyz[(startv)%3]; + strip_xyz[1] = last->index_xyz[(startv+1)%3]; + strip_xyz[2] = last->index_xyz[(startv+2)%3]; + strip_st[0] = last->index_st[(startv)%3]; + strip_st[1] = last->index_st[(startv+1)%3]; + strip_st[2] = last->index_st[(startv+2)%3]; + + strip_tris[0] = starttri; + stripcount = 1; + + m1 = last->index_xyz[(startv+0)%3]; + st1 = last->index_st[(startv+0)%3]; + m2 = last->index_xyz[(startv+2)%3]; + st2 = last->index_st[(startv+2)%3]; + + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] + ; jindex_xyz[k] != m1) + continue; + if (check->index_st[k] != st1) + continue; + if (check->index_xyz[ (k+1)%3 ] != m2) + continue; + if (check->index_st[ (k+1)%3 ] != st2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + m2 = check->index_xyz[ (k+2)%3 ]; + st2 = check->index_st[ (k+2)%3 ]; + + strip_xyz[stripcount+2] = m2; + strip_st[stripcount+2] = st2; + strip_tris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; j bestlen) + { + besttype = type; + bestlen = len; + for (j=0 ; j= 150) + scale = 150.0 / width; + if (height*scale >= 190) + scale = 190.0 / height; + + s_scale = t_scale = scale; + + iwidth = ceil(width*s_scale); + iheight = ceil(height*t_scale); + + iwidth += 4; + iheight += 4; + } + else + { // new style + iwidth = g_fixedwidth / 2; + iheight = g_fixedheight; + + s_scale = (float)(iwidth-4) / width; + t_scale = (float)(iheight-4) / height; + } + +// +// determine which side of each triangle to map the texture to +// + for (i=0 ; i 0) + { + basex = iwidth + 2; + } + else + { + basex = 2; + } + basey = 2; + + for (j=0 ; j<3 ; j++) + { + pbasevert = ptri[i].verts[j]; + + triangle_st[i][j][0] = Q_rint((pbasevert[0] - mins[0]) * s_scale + basex); + triangle_st[i][j][1] = Q_rint((maxs[2] - pbasevert[2]) * t_scale + basey); + } + } + +// make the width a multiple of 4; some hardware requires this, and it ensures +// dword alignment for each scan + swidth = iwidth*2; + model.skinwidth = (swidth + 3) & ~3; + model.skinheight = iheight; +} + + +/* +================= +Cmd_Base +================= +*/ +void Cmd_Base (void) +{ + triangle_t *ptri; + int i, j, k; + int time1; + char file1[1024]; + + GetToken (false); + + if (g_skipmodel || g_release || g_archive) + return; + + printf ("---------------------\n"); + sprintf (file1, "%s/%s.%s", cdarchive, token, trifileext); + printf ("%s\n", file1); + + ExpandPathAndArchive (file1); + + sprintf (file1, "%s/%s.%s", cddir, token, trifileext); + + time1 = FileTime (file1); + if (time1 == -1) + Error ("%s doesn't exist", file1); + +// +// load the base triangles +// + if (do3ds) + Load3DSTriangleList (file1, &ptri, &model.num_tris); + else + LoadTriangleList (file1, &ptri, &model.num_tris); + +// +// get the ST values +// + BuildST (ptri, model.num_tris); + +// +// run through all the base triangles, storing each unique vertex in the +// base vertex list and setting the indirect triangles to point to the base +// vertices +// + for (i=0 ; i= '0' && *s <= '9') + s--; + + strcpy (suffix, s+1); + strcpy (base, frame); + base[s-frame+1] = 0; + + // check for 'run1.tri' + sprintf (file1, "%s/%s%s.%s",cddir, base, suffix, trifileext); + time1 = FileTime (file1); + if (time1 != -1) + { + sprintf (retname, "%s%s.%s", base, suffix, trifileext); + return retname; + } + + // check for 'run.1' + sprintf (file1, "%s/%s.%s",cddir, base, suffix); + time1 = FileTime (file1); + if (time1 != -1) + { + sprintf (retname, "%s.%s", base, suffix); + return retname; + } + + Error ("frame %s could not be found",frame); + return NULL; +} + +/* +=============== +GrabFrame +=============== +*/ +void GrabFrame (char *frame) +{ + triangle_t *ptri; + int i, j; + trivert_t *ptrivert; + int num_tris; + char file1[1024]; + frame_t *fr; + vertexnormals_t vnorms[MAX_VERTS]; + int index_xyz; + char *framefile; + + // the frame 'run1' will be looked for as either + // run.1 or run1.tri, so the new alias sequence save + // feature an be used + framefile = FindFrameFile (frame); + + sprintf (file1, "%s/%s", cdarchive, framefile); + ExpandPathAndArchive (file1); + + sprintf (file1, "%s/%s",cddir, framefile); + + printf ("grabbing %s\n", file1); + + if (model.num_frames >= MAX_FRAMES) + Error ("model.num_frames >= MAX_FRAMES"); + fr = &g_frames[model.num_frames]; + model.num_frames++; + + strcpy (fr->name, frame); + +// +// load the frame +// + if (do3ds) + Load3DSTriangleList (file1, &ptri, &num_tris); + else + LoadTriangleList (file1, &ptri, &num_tris); + + if (num_tris != model.num_tris) + Error ("%s: number of triangles doesn't match base frame\n", file1); + +// +// allocate storage for the frame's vertices +// + ptrivert = fr->v; + + for (i=0 ; imins, fr->maxs); + +// +// store the frame's vertices in the same order as the base. This assumes the +// triangles and vertices in this frame are in exactly the same order as in the +// base +// + for (i=0 ; imins, fr->maxs); + + VectorAdd (vnorms[index_xyz].normalsum, normal, vnorms[index_xyz].normalsum); + vnorms[index_xyz].numnormals++; + } + } + +// +// calculate the vertex normals, match them to the template list, and store the +// index of the best match +// + for (i=0 ; i maxdot) + { + maxdot = dot; + maxdotindex = j; + } + } + + ptrivert[i].lightnormalindex = maxdotindex; + } + + free (ptri); +} + +/* +=============== +Cmd_Frame +=============== +*/ +void Cmd_Frame (void) +{ + while (TokenAvailable()) + { + GetToken (false); + if (g_skipmodel) + continue; + if (g_release || g_archive) + { + model.num_frames = 1; // don't skip the writeout + continue; + } + + H_printf("#define FRAME_%-16s\t%i\n", token, model.num_frames); + + GrabFrame (token); + } +} + + +/* +=============== +Cmd_Skin + +Skins aren't actually stored in the file, only a reference +is saved out to the header file. +=============== +*/ +void Cmd_Skin (void) +{ + byte *palette; + byte *pixels; + int width, height; + byte *cropped; + int y; + char name[1024], savename[1024]; + + GetToken (false); + + if (model.num_skins == MAX_MD2SKINS) + Error ("model.num_skins == MAX_MD2SKINS"); + + if (g_skipmodel) + return; + + sprintf (name, "%s/%s.lbm", cdarchive, token); + strcpy (name, ExpandPathAndArchive( name ) ); +// sprintf (name, "%s/%s.lbm", cddir, token); + + if (TokenAvailable()) + { + GetToken (false); + sprintf (g_skins[model.num_skins], "%s.pcx", token); + sprintf (savename, "%s%s.pcx", gamedir, g_skins[model.num_skins]); + } + else + { + sprintf (savename, "%s/%s.pcx", cddir, token); + sprintf (g_skins[model.num_skins], "%s/%s.pcx", cdpartial, token); + } + + model.num_skins++; + + if (g_skipmodel || g_release || g_archive) + return; + + // load the image + printf ("loading %s\n", name); + Load256Image (name, &pixels, &palette, &width, &height); + RemapZero (pixels, palette, width, height); + + // crop it to the proper size + cropped = malloc (model.skinwidth*model.skinheight); + for (y=0 ; y= sizeof(pf->name)) + Error ("Filename too long for pak: %s", filename); + + len = LoadFile (source, (void **)&buf); + + if (g_compress_pak && len < 4096*1024 ) + { + cblock_t in, out; + cblock_t Huffman (cblock_t in); + + in.count = len; + in.data = buf; + + out = Huffman (in); + + if (out.count < in.count) + { + printf (" compressed from %i to %i\n", in.count, out.count); + free (in.data); + buf = out.data; + len = out.count; + } + else + free (out.data); + } + + strcpy (pf->name, filename); + pf->filepos = LittleLong(ftell(pakfile)); + pf->filelen = LittleLong(len); + pf++; + + SafeWrite (pakfile, buf, len); + + free (buf); +} + + +/* +============== +FinishPak +============== +*/ +void FinishPak (void) +{ + int dirlen; + int d; + int i; + unsigned checksum; + + if (!g_pak) + return; + + pakheader.id[0] = 'P'; + pakheader.id[1] = 'A'; + pakheader.id[2] = 'C'; + pakheader.id[3] = 'K'; + dirlen = (byte *)pf - (byte *)pfiles; + pakheader.dirofs = LittleLong(ftell(pakfile)); + pakheader.dirlen = LittleLong(dirlen); + + checksum = Com_BlockChecksum ( (void *)pfiles, dirlen ); + + SafeWrite (pakfile, pfiles, dirlen); + + i = ftell (pakfile); + + fseek (pakfile, 0, SEEK_SET); + SafeWrite (pakfile, &pakheader, sizeof(pakheader)); + fclose (pakfile); + + d = pf - pfiles; + printf ("%i files packed in %i bytes\n",d, i); + printf ("checksum: 0x%x\n", checksum); +} + + +/* +=============== +Cmd_File + +This is only used to cause a file to be copied during a release +build (default.cfg, maps, etc) +=============== +*/ +void Cmd_File (void) +{ + GetToken (false); + ReleaseFile (token); +} + +/* +=============== +PackDirectory_r + +=============== +*/ +#ifdef _WIN32 +#include "io.h" +void PackDirectory_r (char *dir) +{ + struct _finddata_t fileinfo; + int handle; + char dirstring[1024]; + char filename[1024]; + + sprintf (dirstring, "%s%s/*.*", gamedir, dir); + + handle = _findfirst (dirstring, &fileinfo); + if (handle == -1) + return; + + do + { + sprintf (filename, "%s/%s", dir, fileinfo.name); + if (fileinfo.attrib & _A_SUBDIR) + { // directory + if (fileinfo.name[0] != '.') // don't pak . and .. + PackDirectory_r (filename); + continue; + } + // copy or pack the file + ReleaseFile (filename); + } while (_findnext( handle, &fileinfo ) != -1); + + _findclose (handle); +} +#else + +#include +#ifdef NeXT +#include +#else +#include +#endif + +void PackDirectory_r (char *dir) +{ +#ifdef NeXT + struct direct **namelist, *ent; +#else + struct dirent **namelist, *ent; +#endif + int count; + struct stat st; + int i; + int len; + char fullname[1024]; + char dirstring[1024]; + char *name; + + sprintf (dirstring, "%s%s", gamedir, dir); + count = scandir(dirstring, &namelist, NULL, NULL); + + for (i=0 ; id_name; + + if (name[0] == '.') + continue; + + sprintf (fullname, "%s/%s", dir, name); + sprintf (dirstring, "%s%s/%s", gamedir, dir, name); + + if (stat (dirstring, &st) == -1) + Error ("fstating %s", pf->name); + if (st.st_mode & S_IFDIR) + { // directory + PackDirectory_r (fullname); + continue; + } + + // copy or pack the file + ReleaseFile (fullname); + } +} +#endif + + +/* +=============== +Cmd_Dir + +This is only used to cause a directory to be copied during a +release build (sounds, etc) +=============== +*/ +void Cmd_Dir (void) +{ + GetToken (false); + PackDirectory_r (token); +} + +//======================================================================== + +#define MAX_RTEX 16384 +int numrtex; +char rtex[MAX_RTEX][64]; + +void ReleaseTexture (char *name) +{ + int i; + char path[1024]; + + for (i=0 ; i= argc) + Error ("usage: qgrab [-archive ] [-release ] [-only ] [-3ds] file.qgr"); + + if (do3ds) + trifileext = ext_3ds; + else + trifileext = ext_tri; + + for ( ; i +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=qdata - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "qdata.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "qdata.mak" CFG="qdata - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "qdata - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "qdata - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "qdata - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "qdata - Win32 Release" +# Name "qdata - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=..\common\bspfile.c +# End Source File +# Begin Source File + +SOURCE=..\common\cmdlib.c +# End Source File +# Begin Source File + +SOURCE=.\images.c +# End Source File +# Begin Source File + +SOURCE=..\common\l3dslib.c +# End Source File +# Begin Source File + +SOURCE=..\common\lbmlib.c +# End Source File +# Begin Source File + +SOURCE=..\common\mathlib.c +# End Source File +# Begin Source File + +SOURCE=..\common\mdfour.c +# End Source File +# Begin Source File + +SOURCE=.\models.c +# End Source File +# Begin Source File + +SOURCE=.\qdata.c +# End Source File +# Begin Source File + +SOURCE=..\common\scriplib.c +# End Source File +# Begin Source File + +SOURCE=.\sprites.c +# End Source File +# Begin Source File + +SOURCE=.\tables.c +# End Source File +# Begin Source File + +SOURCE=..\common\threads.c +# End Source File +# Begin Source File + +SOURCE=..\common\trilib.c +# End Source File +# Begin Source File + +SOURCE=.\video.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\anorms.h +# End Source File +# Begin Source File + +SOURCE=..\common\bspfile.h +# End Source File +# Begin Source File + +SOURCE=..\common\cmdlib.h +# End Source File +# Begin Source File + +SOURCE=..\common\l3dslib.h +# End Source File +# Begin Source File + +SOURCE=..\common\lbmlib.h +# End Source File +# Begin Source File + +SOURCE=..\common\mathlib.h +# End Source File +# Begin Source File + +SOURCE=.\modelgen.h +# End Source File +# Begin Source File + +SOURCE=.\qdata.h +# End Source File +# Begin Source File + +SOURCE=..\common\qfiles.h +# End Source File +# Begin Source File + +SOURCE=..\common\scriplib.h +# End Source File +# Begin Source File + +SOURCE=..\common\threads.h +# End Source File +# Begin Source File + +SOURCE=..\common\trilib.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/tools/quake2/extra/qdata/qdata.dsw b/tools/quake2/extra/qdata/qdata.dsw new file mode 100644 index 00000000..5a1c558b --- /dev/null +++ b/tools/quake2/extra/qdata/qdata.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "qdata"=.\qdata.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/tools/quake2/extra/qdata/qdata.h b/tools/quake2/extra/qdata/qdata.h new file mode 100644 index 00000000..bd8e63c3 --- /dev/null +++ b/tools/quake2/extra/qdata/qdata.h @@ -0,0 +1,89 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// qdata.h + + +#include +#include +#include +#include +#include + +#include "cmdlib.h" +#include "scriplib.h" +#include "mathlib.h" +#include "trilib.h" +#include "lbmlib.h" +#include "threads.h" +#include "l3dslib.h" +#include "bspfile.h" + +void Cmd_Modelname (void); +void Cmd_Base (void); +void Cmd_Cd (void); +void Cmd_Origin (void); +void Cmd_ScaleUp (void); +void Cmd_Frame (void); +void Cmd_Modelname (void); +void Cmd_Skin (void); +void Cmd_Skinsize (void); +void FinishModel (void); + +void Cmd_Inverse16Table( void ); + +void Cmd_SpriteName (void); +void Cmd_Load (void); +void Cmd_SpriteFrame (void); +void FinishSprite (void); + +void Cmd_Grab (void); +void Cmd_Raw (void); +void Cmd_Mip (void); +void Cmd_Environment (void); +void Cmd_Colormap (void); + +void Cmd_File (void); +void Cmd_Dir (void); +void Cmd_StartWad (void); +void Cmd_EndWad (void); +void Cmd_Mippal (void); +void Cmd_Mipdir (void); +void Cmd_Alphalight (void); + +void Cmd_Video (void); + +void RemapZero (byte *pixels, byte *palette, int width, int height); + +void ReleaseFile (char *filename); + +extern byte *byteimage, *lbmpalette; +extern int byteimagewidth, byteimageheight; + +extern qboolean g_release; // don't grab, copy output data to new tree +extern char g_releasedir[1024]; // c:\quake2\baseq2, etc +extern qboolean g_archive; // don't grab, copy source data to new tree +extern qboolean do3ds; +extern char g_only[256]; // if set, only grab this cd +extern qboolean g_skipmodel; // set true when a cd is not g_only + +extern char *trifileext; diff --git a/tools/quake2/extra/qdata/qdata.mak b/tools/quake2/extra/qdata/qdata.mak new file mode 100644 index 00000000..5639dab1 --- /dev/null +++ b/tools/quake2/extra/qdata/qdata.mak @@ -0,0 +1,549 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=qdata - Win32 Debug +!MESSAGE No configuration specified. Defaulting to qdata - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "qdata - Win32 Release" && "$(CFG)" != "qdata - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "qdata.mak" CFG="qdata - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "qdata - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "qdata - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "qdata - Win32 Debug" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "qdata - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\qdata.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\images.obj" + -@erase "$(INTDIR)\l3dslib.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\models.obj" + -@erase "$(INTDIR)\qdata.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\sprites.obj" + -@erase "$(INTDIR)\tables.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\trilib.obj" + -@erase "$(OUTDIR)\qdata.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /I "../common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "../common" /D "WIN32" /D "NDEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/qdata.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qdata.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/qdata.pdb" /machine:I386 /out:"$(OUTDIR)/qdata.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\images.obj" \ + "$(INTDIR)\l3dslib.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\models.obj" \ + "$(INTDIR)\qdata.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\sprites.obj" \ + "$(INTDIR)\tables.obj" \ + "$(INTDIR)\threads.obj" \ + "$(INTDIR)\trilib.obj" + +"$(OUTDIR)\qdata.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\qdata.exe" + +CLEAN : + -@erase "$(INTDIR)\bspfile.obj" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\images.obj" + -@erase "$(INTDIR)\l3dslib.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\models.obj" + -@erase "$(INTDIR)\qdata.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\sprites.obj" + -@erase "$(INTDIR)\tables.obj" + -@erase "$(INTDIR)\threads.obj" + -@erase "$(INTDIR)\trilib.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\qdata.exe" + -@erase "$(OUTDIR)\qdata.ilk" + -@erase "$(OUTDIR)\qdata.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "../common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "../common" /D "WIN32" /D "_DEBUG"\ + /D "_CONSOLE" /Fp"$(INTDIR)/qdata.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qdata.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/qdata.pdb" /debug /machine:I386 /out:"$(OUTDIR)/qdata.exe" +LINK32_OBJS= \ + "$(INTDIR)\bspfile.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\images.obj" \ + "$(INTDIR)\l3dslib.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\models.obj" \ + "$(INTDIR)\qdata.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\sprites.obj" \ + "$(INTDIR)\tables.obj" \ + "$(INTDIR)\threads.obj" \ + "$(INTDIR)\trilib.obj" + +"$(OUTDIR)\qdata.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "qdata - Win32 Release" +# Name "qdata - Win32 Debug" + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\images.c +DEP_CPP_IMAGE=\ + "..\common\qfiles.h"\ + ".\../common\bspfile.h"\ + ".\../common\cmdlib.h"\ + ".\../common\l3dslib.h"\ + ".\../common\lbmlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\scriplib.h"\ + ".\../common\threads.h"\ + ".\../common\trilib.h"\ + ".\qdata.h"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\images.obj" : $(SOURCE) $(DEP_CPP_IMAGE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\modelgen.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qdata.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\sprites.c +DEP_CPP_SPRIT=\ + "..\common\qfiles.h"\ + ".\../common\bspfile.h"\ + ".\../common\cmdlib.h"\ + ".\../common\l3dslib.h"\ + ".\../common\lbmlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\scriplib.h"\ + ".\../common\threads.h"\ + ".\../common\trilib.h"\ + ".\qdata.h"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\sprites.obj" : $(SOURCE) $(DEP_CPP_SPRIT) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\l3dslib.c +DEP_CPP_L3DSL=\ + ".\../common\cmdlib.h"\ + ".\../common\l3dslib.h"\ + ".\../common\mathlib.h"\ + ".\../common\trilib.h"\ + + +"$(INTDIR)\l3dslib.obj" : $(SOURCE) $(DEP_CPP_L3DSL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\lbmlib.c +DEP_CPP_LBMLI=\ + ".\../common\cmdlib.h"\ + ".\../common\lbmlib.h"\ + + +"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.c +DEP_CPP_MATHL=\ + ".\../common\cmdlib.h"\ + ".\../common\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\scriplib.c +DEP_CPP_SCRIP=\ + ".\../common\cmdlib.h"\ + ".\../common\scriplib.h"\ + + +"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\threads.c +DEP_CPP_THREA=\ + ".\../common\cmdlib.h"\ + ".\../common\threads.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\threads.obj" : $(SOURCE) $(DEP_CPP_THREA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\trilib.c +DEP_CPP_TRILI=\ + ".\../common\cmdlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\trilib.h"\ + + +"$(INTDIR)\trilib.obj" : $(SOURCE) $(DEP_CPP_TRILI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.c +DEP_CPP_CMDLI=\ + ".\../common\cmdlib.h"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\models.c +DEP_CPP_MODEL=\ + "..\common\qfiles.h"\ + ".\../common\bspfile.h"\ + ".\../common\cmdlib.h"\ + ".\../common\l3dslib.h"\ + ".\../common\lbmlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\scriplib.h"\ + ".\../common\threads.h"\ + ".\../common\trilib.h"\ + ".\anorms.h"\ + ".\qdata.h"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\models.obj" : $(SOURCE) $(DEP_CPP_MODEL) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qdata.c +DEP_CPP_QDATA=\ + "..\common\qfiles.h"\ + ".\../common\bspfile.h"\ + ".\../common\cmdlib.h"\ + ".\../common\l3dslib.h"\ + ".\../common\lbmlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\scriplib.h"\ + ".\../common\threads.h"\ + ".\../common\trilib.h"\ + ".\qdata.h"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\qdata.obj" : $(SOURCE) $(DEP_CPP_QDATA) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\mathlib.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\lbmlib.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\cmdlib.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\tables.c +DEP_CPP_TABLE=\ + "..\common\qfiles.h"\ + ".\../common\bspfile.h"\ + ".\../common\cmdlib.h"\ + ".\../common\l3dslib.h"\ + ".\../common\lbmlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\scriplib.h"\ + ".\../common\threads.h"\ + ".\../common\trilib.h"\ + ".\qdata.h"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + + +"$(INTDIR)\tables.obj" : $(SOURCE) $(DEP_CPP_TABLE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\qfiles.h + +!IF "$(CFG)" == "qdata - Win32 Release" + +!ELSEIF "$(CFG)" == "qdata - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=..\common\bspfile.c +DEP_CPP_BSPFI=\ + "..\common\qfiles.h"\ + ".\../common\bspfile.h"\ + ".\../common\cmdlib.h"\ + ".\../common\mathlib.h"\ + ".\../common\scriplib.h"\ + + +"$(INTDIR)\bspfile.obj" : $(SOURCE) $(DEP_CPP_BSPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/tools/quake2/extra/qdata/sprites.c b/tools/quake2/extra/qdata/sprites.c new file mode 100644 index 00000000..7bc308a8 --- /dev/null +++ b/tools/quake2/extra/qdata/sprites.c @@ -0,0 +1,228 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qdata.h" + +#define MAX_SPRFRAMES MAX_MD2SKINS + +dsprite_t sprite; +dsprframe_t frames[MAX_SPRFRAMES]; + +byte *byteimage, *lbmpalette; +int byteimagewidth, byteimageheight; + +char spritename[1024]; + + +void FinishSprite (void); +void Cmd_Spritename (void); + + + +/* +============== +FinishSprite +============== +*/ +void FinishSprite (void) +{ + FILE *spriteouthandle; + int i, curframe; + dsprite_t spritetemp; + char savename[1024]; + + if (sprite.numframes == 0) + return; + + if (!strlen(spritename)) + Error ("Didn't name sprite file"); + + sprintf (savename, "%s%s.sp2", gamedir, spritename); + + if (g_release) + { + char name[1024]; + + sprintf (name, "%s.sp2", spritename); + ReleaseFile (name); + spritename[0] = 0; // clear for a new sprite + sprite.numframes = 0; + return; + } + + + printf ("saving in %s\n", savename); + CreatePath (savename); + spriteouthandle = SafeOpenWrite (savename); + + +// +// write out the sprite header +// + spritetemp.ident = LittleLong (IDSPRITEHEADER); + spritetemp.version = LittleLong (SPRITE_VERSION); + spritetemp.numframes = LittleLong (sprite.numframes); + + SafeWrite (spriteouthandle, &spritetemp, 12); + +// +// write out the frames +// + curframe = 0; + + for (i=0 ; i 256) || (h > 256)) + Error ("Sprite has a dimension longer than 256"); + + xh = xl+w; + yh = yl+h; + + if (sprite.numframes >= MAX_SPRFRAMES) + Error ("Too many frames; increase MAX_SPRFRAMES\n"); + + pframe = &frames[sprite.numframes]; + pframe->width = w; + pframe->height = h; + pframe->origin_x = ox; + pframe->origin_y = oy; + sprintf (pframe->name, "%s_%i.pcx", spritename, sprite.numframes); + sprintf (savename, "%s%s_%i.pcx", gamedir, spritename, sprite.numframes); + sprite.numframes++; + + if (g_release) + { + ReleaseFile (pframe->name); + return; + } + + // crop it to the proper size + cropped = malloc (w*h); + for (y=0 ; y> 5 ) & 63 ) << 2; + b[0] = ( ( color >> 11 ) & 31 ) << 3; + + for ( i = 0; i < 256; i++ ) + { + r[1] = ( d_8to24table[i] >> 0 ) & 0xFF; + g[1] = ( d_8to24table[i] >> 8 ) & 0xFF; + b[1] = ( d_8to24table[i] >> 16 ) & 0xFF; + + d = ( r[1] - r[0] ) * ( r[1] - r[0] ) + + ( g[1] - g[0] ) * ( g[1] - g[0] ) + + ( b[1] - b[0] ) * ( b[1] - b[0] ); + + if ( d < closest_distance_so_far ) + { + closest_distance_so_far = d; + closest_so_far = i; + } + } + + return closest_so_far; +} +*/ + +extern byte BestColor( int, int, int, int, int ); + +void Inverse16_BuildTable( void ) +{ + int i; + + /* + ** create the 16-to-8 table + */ + for ( i = 0; i < 65536; i++ ) + { + int r = i & 31; + int g = ( i >> 5 ) & 63; + int b = ( i >> 11 ) & 31; + + r <<= 3; + g <<= 2; + b <<= 3; + + inverse16to8table[i] = BestColor( r, g, b, 0, 255 ); + } +} + +void Alphalight_Thread (int i) +{ + int j; + float r, g, b; + float mr, mg, mb, ma; + float distortion, bestdistortion; + float v; + + r = (i>>10) * (1.0/16); + g = ((i>>5)&31) * (1.0/16); + b = (i&31) * (1.0/16); + + bestdistortion = 999999; + for (j=0 ; j<16*16*16*16 ; j++) + { + mr = (j>>12) * (1.0/16); + mg = ((j>>8)&15) * (1.0/16); + mb = ((j>>4)&15) * (1.0/16); + ma = (j&15) * (1.0/16); + + v = r * 0.5 - (mr*ma + 0.5*(1.0-ma)); + distortion = v*v; + v = g * 0.5 - (mg*ma + 0.5*(1.0-ma)); + distortion += v*v; + v = b * 0.5 - (mb*ma + 0.5*(1.0-ma)); + distortion += v*v; + + distortion *= 1.0 + ma*4; + + if (distortion < bestdistortion) + { + bestdistortion = distortion; + alphamap[i] = j; + } + } +} + +void Cmd_Alphalight (void) +{ + char savename[1024]; + + GetToken (false); + + if (g_release) + { + ReleaseFile (token); + return; + } + + sprintf (savename, "%s%s", gamedir, token); + printf ("Building alphalight table...\n"); + + RunThreadsOnIndividual (32*32*32, true, Alphalight_Thread); + + SaveFile (savename, (byte *)alphamap, sizeof(alphamap)); +} + + +void Cmd_Inverse16Table( void ) +{ + char savename[1024]; + + if ( g_release ) + { + sprintf (savename, "pics/16to8.dat"); + ReleaseFile( savename ); + return; + } + + sprintf (savename, "%spics/16to8.dat", gamedir); + printf ("Building inverse 16-to-8 table...\n"); + + Inverse16_BuildTable(); + + SaveFile( savename, (byte *) inverse16to8table, sizeof( inverse16to8table ) ); +} diff --git a/tools/quake2/extra/qdata/video.c b/tools/quake2/extra/qdata/video.c new file mode 100644 index 00000000..b2df1493 --- /dev/null +++ b/tools/quake2/extra/qdata/video.c @@ -0,0 +1,1259 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qdata.h" + +byte *soundtrack; +char base[32]; + +/* +=============================================================================== + +WAV loading + +=============================================================================== +*/ + +typedef struct +{ + int rate; + int width; + int channels; + int loopstart; + int samples; + int dataofs; // chunk starts this many bytes from file start +} wavinfo_t; + + +byte *data_p; +byte *iff_end; +byte *last_chunk; +byte *iff_data; +int iff_chunk_len; + + +int samplecounts[0x10000]; + +wavinfo_t wavinfo; + +short GetLittleShort(void) +{ + short val = 0; + val = *data_p; + val = val + (*(data_p+1)<<8); + data_p += 2; + return val; +} + +int GetLittleLong(void) +{ + int val = 0; + val = *data_p; + val = val + (*(data_p+1)<<8); + val = val + (*(data_p+2)<<16); + val = val + (*(data_p+3)<<24); + data_p += 4; + return val; +} + +void FindNextChunk(char *name) +{ + while (1) + { + data_p=last_chunk; + + if (data_p >= iff_end) + { // didn't find the chunk + data_p = NULL; + return; + } + + data_p += 4; + iff_chunk_len = GetLittleLong(); + if (iff_chunk_len < 0) + { + data_p = NULL; + return; + } +// if (iff_chunk_len > 1024*1024) +// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); + data_p -= 8; + last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 ); + if (!strncmp(data_p, name, 4)) + return; + } +} + +void FindChunk(char *name) +{ + last_chunk = iff_data; + FindNextChunk (name); +} + + +void DumpChunks(void) +{ + char str[5]; + + str[4] = 0; + data_p=iff_data; + do + { + memcpy (str, data_p, 4); + data_p += 4; + iff_chunk_len = GetLittleLong(); + printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len); + data_p += (iff_chunk_len + 1) & ~1; + } while (data_p < iff_end); +} + +/* +============ +GetWavinfo +============ +*/ +wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) +{ + wavinfo_t info; + int i; + int format; + int samples; + + memset (&info, 0, sizeof(info)); + + if (!wav) + return info; + + iff_data = wav; + iff_end = wav + wavlength; + +// find "RIFF" chunk + FindChunk("RIFF"); + if (!(data_p && !strncmp(data_p+8, "WAVE", 4))) + { + printf("Missing RIFF/WAVE chunks\n"); + return info; + } + +// get "fmt " chunk + iff_data = data_p + 12; +// DumpChunks (); + + FindChunk("fmt "); + if (!data_p) + { + printf("Missing fmt chunk\n"); + return info; + } + data_p += 8; + format = GetLittleShort(); + if (format != 1) + { + printf("Microsoft PCM format only\n"); + return info; + } + + info.channels = GetLittleShort(); + info.rate = GetLittleLong(); + data_p += 4+2; + info.width = GetLittleShort() / 8; + +// get cue chunk + FindChunk("cue "); + if (data_p) + { + data_p += 32; + info.loopstart = GetLittleLong(); +// Com_Printf("loopstart=%d\n", sfx->loopstart); + + // if the next chunk is a LIST chunk, look for a cue length marker + FindNextChunk ("LIST"); + if (data_p) + { + if (!strncmp (data_p + 28, "mark", 4)) + { // this is not a proper parse, but it works with cooledit... + data_p += 24; + i = GetLittleLong (); // samples in loop + info.samples = info.loopstart + i; + } + } + } + else + info.loopstart = -1; + +// find data chunk + FindChunk("data"); + if (!data_p) + { + printf("Missing data chunk\n"); + return info; + } + + data_p += 4; + samples = GetLittleLong (); + + if (info.samples) + { + if (samples < info.samples) + Error ("Sound %s has a bad loop length", name); + } + else + info.samples = samples; + + info.dataofs = data_p - wav; + + return info; +} + +//===================================================================== + +/* +============== +LoadSoundtrack +============== +*/ +void LoadSoundtrack (void) +{ + char name[1024]; + FILE *f; + int len; + int i, val, j; + + soundtrack = NULL; + sprintf (name, "%svideo/%s/%s.wav", gamedir, base, base); + printf ("%s\n", name); + f = fopen (name, "rb"); + if (!f) + { + printf ("no soundtrack for %s\n", base); + return; + } + len = Q_filelength(f); + soundtrack = malloc(len); + fread (soundtrack, 1, len, f); + fclose (f); + + wavinfo = GetWavinfo (name, soundtrack, len); + + // count samples for compression + memset (samplecounts, 0, sizeof(samplecounts)); + + j = wavinfo.samples/2; + for (i=0 ; i wavinfo.samples || !soundtrack) + fwrite (&empty, 1, width, output); + else + fwrite (soundtrack + wavinfo.dataofs + sample*width, 1, width,output); + } +} + +//========================================================================== + +/* +================== +MTF +================== +*/ +cblock_t MTF (cblock_t in) +{ + int i, j, b, code; + byte *out_p; + int index[256]; + cblock_t out; + + out_p = out.data = malloc(in.count + 4); + + // write count + *out_p++ = in.count&255; + *out_p++ = (in.count>>8)&255; + *out_p++ = (in.count>>16)&255; + *out_p++ = (in.count>>24)&255; + + for (i=0 ; i<256 ; i++) + index[i] = i; + + for (i=0 ; i b2) + return 1; + if (++i1 == bwt_size) + i1 = 0; + if (++i2 == bwt_size) + i2 = 0; + } + + return 0; +} + +/* +================== +BWT +================== +*/ +cblock_t BWT (cblock_t in) +{ + int *sorted; + int i; + byte *out_p; + cblock_t out; + + bwt_size = in.count; + bwt_data = in.data; + + sorted = malloc(in.count*sizeof(*sorted)); + for (i=0 ; i>8)&255; + *out_p++ = (in.count>>16)&255; + *out_p++ = (in.count>>24)&255; + + // write head index + for (i=0 ; i>8)&255; + *out_p++ = (i>>16)&255; + *out_p++ = (i>>24)&255; + + // write the L column + for (i=0 ; i 32) + Error ("bitcount > 32"); + charbits[nodenum] = bits; + charbitscount[nodenum] = bitcount; + return; + } + + node = &hnodes[nodenum]; + bits <<= 1; + BuildChars (node->children[0], bits, bitcount+1); + bits |= 1; + BuildChars (node->children[1], bits, bitcount+1); +} + + +/* +================== +Huffman +================== +*/ +cblock_t Huffman (cblock_t in) +{ + int i; + hnode_t *node; + int outbits, c; + unsigned bits; + byte *out_p; + cblock_t out; + int max, maxchar; + + // count + memset (hnodes, 0, sizeof(hnodes)); + for (i=0 ; i max) + { + max = hnodes[i].count; + maxchar = i; + } + } + if (max == 0) + Error ("Huffman: max == 0"); + + for (i=0 ; i<256 ; i++) + { + hnodes[i].count = (hnodes[i].count*255+max-1) / max; + } + + // build the nodes + numhnodes = 256; + while (numhnodes != 511) + { + node = &hnodes[numhnodes]; + + // pick two lowest counts + node->children[0] = SmallestNode (); + if (node->children[0] == -1) + break; // no more + + node->children[1] = SmallestNode (); + if (node->children[1] == -1) + { + if (node->children[0] != numhnodes-1) + Error ("Bad smallestnode"); + break; + } + node->count = hnodes[node->children[0]].count + + hnodes[node->children[1]].count; + numhnodes++; + } + + BuildChars (numhnodes-1, 0, 0); + + out_p = out.data = malloc(in.count*2 + 1024); + memset (out_p, 0, in.count*2+1024); + + // write count + *out_p++ = in.count&255; + *out_p++ = (in.count>>8)&255; + *out_p++ = (in.count>>16)&255; + *out_p++ = (in.count>>24)&255; + + // save out the 256 normalized counts so the tree can be recreated + for (i=0 ; i<256 ; i++) + *out_p++ = hnodes[i].count; + + // write bits + outbits = 0; + for (i=0 ; i>3] |= 1<<(outbits&7); + outbits++; + } + } + + out_p += (outbits+7)>>3; + + out.count = out_p - out.data; + + return out; +} + +//========================================================================== + +/* +================== +RLE +================== +*/ +#define RLE_CODE 0xe8 +#define RLE_TRIPPLE 0xe9 + +int rle_counts[256]; +int rle_bytes[256]; + +cblock_t RLE (cblock_t in) +{ + int i; + byte *out_p; + int val; + int repeat; + cblock_t out; + + out_p = out.data = malloc (in.count*2); + + // write count + *out_p++ = in.count&255; + *out_p++ = (in.count>>8)&255; + *out_p++ = (in.count>>16)&255; + *out_p++ = (in.count>>24)&255; + + for (i=0 ; i 3 || val == RLE_CODE) + { + *out_p++ = RLE_CODE; + *out_p++ = val; + *out_p++ = repeat; + } + else + { + while (repeat--) + *out_p++ = val; + } + } + + out.count = out_p - out.data; + return out; +} + +//========================================================================== + +unsigned lzss_head[256]; +unsigned lzss_next[0x20000]; + +/* +================== +LZSS +================== +*/ +#define BACK_WINDOW 0x10000 +#define BACK_BITS 16 +#define FRONT_WINDOW 16 +#define FRONT_BITS 4 +cblock_t LZSS (cblock_t in) +{ + int i; + byte *out_p; + cblock_t out; + int val; + int j, start, max; + int bestlength, beststart; + int outbits; + +if (in.count >= sizeof(lzss_next)/4) +Error ("LZSS: too big"); + + memset (lzss_head, -1, sizeof(lzss_head)); + + out_p = out.data = malloc (in.count*2); + memset (out.data, 0, in.count*2); + + // write count + *out_p++ = in.count&255; + *out_p++ = (in.count>>8)&255; + *out_p++ = (in.count>>16)&255; + *out_p++ = (in.count>>24)&255; + + outbits = 0; + for (i=0 ; i in.count) + max = in.count - i; + + start = lzss_head[val]; + while (start != -1 && start >= i-BACK_WINDOW) + { + // count match length + for (j=0 ; j bestlength) + { + bestlength = j; + beststart = start; + } + start = lzss_next[start]; + } + +#else +// slow simple search + // search for a match + max = FRONT_WINDOW; + if (i + max > in.count) + max = in.count - i; + + start = i - BACK_WINDOW; + if (start < 0) + start = 0; + bestlength = 0; + beststart = 0; + for ( ; start < i ; start++) + { + if (in.data[start] != val) + continue; + // count match length + for (j=0 ; j bestlength) + { + bestlength = j; + beststart = start; + } + } +#endif + beststart = BACK_WINDOW - (i-beststart); + + if (bestlength < 3) + { // output a single char + bestlength = 1; + + out_p[outbits>>3] |= 1<<(outbits&7); // set bit to mark char + outbits++; + for (j=0 ; j<8 ; j++, outbits++) + if (val & (1<>3] |= 1<<(outbits&7); + } + else + { // output a phrase + outbits++; // leave a 0 bit to mark phrase + for (j=0 ; j>3] |= 1<<(outbits&7); + for (j=0 ; j>3] |= 1<<(outbits&7); + } + + while (bestlength--) + { + val = in.data[i]; + lzss_next[i] = lzss_head[val]; + lzss_head[val] = i; + i++; + } + } + + out_p += (outbits+7)>>3; + out.count = out_p - out.data; + return out; +} + +//========================================================================== + +#define MIN_REPT 15 +#define MAX_REPT 0 +#define HUF_TOKENS (256+MAX_REPT) + +unsigned charbits1[256][HUF_TOKENS]; +int charbitscount1[256][HUF_TOKENS]; + +hnode_t hnodes1[256][HUF_TOKENS*2]; +int numhnodes1[256]; + +int order0counts[256]; + +/* +================== +SmallestNode1 +================== +*/ +int SmallestNode1 (hnode_t *hnodes, int numhnodes) +{ + int i; + int best, bestnode; + + best = 99999999; + bestnode = -1; + for (i=0 ; i 32) + Error ("bitcount > 32"); + charbits1[prev][nodenum] = bits; + charbitscount1[prev][nodenum] = bitcount; + return; + } + + node = &hnodes1[prev][nodenum]; + bits <<= 1; + BuildChars1 (prev, node->children[0], bits, bitcount+1); + bits |= 1; + BuildChars1 (prev, node->children[1], bits, bitcount+1); +} + + +/* +================== +BuildTree1 +================== +*/ +void BuildTree1 (int prev) +{ + hnode_t *node, *nodebase; + int numhnodes; + + // build the nodes + numhnodes = HUF_TOKENS; + nodebase = hnodes1[prev]; + while (1) + { + node = &nodebase[numhnodes]; + + // pick two lowest counts + node->children[0] = SmallestNode1 (nodebase, numhnodes); + if (node->children[0] == -1) + break; // no more + + node->children[1] = SmallestNode1 (nodebase, numhnodes); + if (node->children[1] == -1) + break; + + node->count = nodebase[node->children[0]].count + + nodebase[node->children[1]].count; + numhnodes++; + } + numhnodes1[prev] = numhnodes-1; + BuildChars1 (prev, numhnodes-1, 0, 0); +} + + +/* +================== +Huffman1_Count +================== +*/ +void Huffman1_Count (cblock_t in) +{ + int i; + int prev; + int v; + int rept; + + prev = 0; + for (i=0 ; i MIN_REPT) + { + hnodes1[prev][255+rept].count++; + i += rept-1; + } +#endif + } +} + + +/* +================== +Huffman1_Build +================== +*/ +byte scaled[256][HUF_TOKENS]; +void Huffman1_Build (FILE *f) +{ + int i, j, v; + int max; + int total; + + for (i=0 ; i<256 ; i++) + { + // normalize and save the counts + max = 0; + for (j=0 ; j max) + max = hnodes1[i][j].count; + } + if (max == 0) + max = 1; + total = 0; + for (j=0 ; j 255) + Error ("v > 255"); + scaled[i][j] = hnodes1[i][j].count = v; + if (v) + total++; + } + if (total == 1) + { // must have two tokens + if (!scaled[i][0]) + scaled[i][0] = hnodes1[i][0].count = 1; + else + scaled[i][1] = hnodes1[i][1].count = 1; + } + + BuildTree1 (i); + } + +#if 0 + // count up the total bits + total = 0; + for (i=0 ; i<256 ; i++) + for (j=0 ; j<256 ; j++) + total += charbitscount1[i][j] * hnodes1[i][j].count; + + total = (total+7)/8; + printf ("%i bytes huffman1 compressed\n", total); +#endif + + fwrite (scaled, 1, sizeof(scaled), f); +} + +/* +================== +Huffman1 + +Order 1 compression with pre-built table +================== +*/ +cblock_t Huffman1 (cblock_t in) +{ + int i; + int outbits, c; + unsigned bits; + byte *out_p; + cblock_t out; + int prev; + int v; + int rept; + + out_p = out.data = malloc(in.count*2 + 1024); + memset (out_p, 0, in.count*2+1024); + + // write count + *out_p++ = in.count&255; + *out_p++ = (in.count>>8)&255; + *out_p++ = (in.count>>16)&255; + *out_p++ = (in.count>>24)&255; + + // write bits + outbits = 0; + prev = 0; + for (i=0 ; i>3] |= 1<<(outbits&7); + outbits++; + } + + prev = v; +#if 1 + // check for repeat encodes + for (rept=1 ; i+rept < in.count && rept < MAX_REPT ; rept++) + if (in.data[i+rept] != v) + break; + if (rept > MIN_REPT) + { + c = charbitscount1[prev][255+rept]; + bits = charbits1[prev][255+rept]; + if (!c) + Error ("!bits"); + while (c) + { + c--; + if (bits & (1<>3] |= 1<<(outbits&7); + outbits++; + } + i += rept-1; + } +#endif + } + + out_p += (outbits+7)>>3; + + out.count = out_p - out.data; + + return out; +} + +//========================================================================== + + +/* +=================== +LoadFrame +=================== +*/ +cblock_t LoadFrame (char *base, int frame, int digits, byte **palette) +{ + int ten3, ten2, ten1, ten0; + cblock_t in; + int width, height; + char name[1024]; + FILE *f; + + in.data = NULL; + in.count = -1; + + ten3 = frame/1000; + ten2 = (frame-ten3*1000)/100; + ten1 = (frame-ten3*1000-ten2*100)/10; + ten0 = frame%10; + + if (digits == 4) + sprintf (name, "%svideo/%s/%s%i%i%i%i.pcx", gamedir, base, base, ten3, ten2, ten1, ten0); + else + sprintf (name, "%svideo/%s/%s%i%i%i.pcx", gamedir, base, base, ten2, ten1, ten0); + + f = fopen(name, "rb"); + if (!f) + { + in.data = NULL; + return in; + } + fclose (f); + + printf ("%s\n", name); + Load256Image (name, &in.data, palette, &width, &height); + in.count = width*height; +// FIXME: map 0 and 255! + +#if 0 + // rle compress + rle = RLE(in); + free (in.data); + + return rle; +#endif + + return in; +} + +/* +=============== +Cmd_Video + +video +=============== +*/ +void Cmd_Video (void) +{ + char savename[1024]; + char name[1024]; + FILE *output; + int startframe, frame; + byte *palette; + int width, height; + byte current_palette[768]; + int command; + int i; + int digits; + cblock_t in, huffman; + int swap; + + + GetToken (false); + strcpy (base, token); + if (g_release) + { +// sprintf (savename, "video/%s.cin", token); +// ReleaseFile (savename); + return; + } + + GetToken (false); + digits = atoi(token); + + // optionally skip frames + if (TokenAvailable ()) + { + GetToken (false); + startframe = atoi(token); + } + else + startframe=0; + + sprintf (savename, "%svideo/%s.cin", gamedir, base); + + + // clear stuff + memset (charbits1, 0, sizeof(charbits1)); + memset (charbitscount1, 0, sizeof(charbitscount1)); + memset (hnodes1, 0, sizeof(hnodes1)); + memset (numhnodes1, 0, sizeof(numhnodes1)); + memset (order0counts, 0, sizeof(order0counts)); + + + // load the entire sound wav file if present + LoadSoundtrack (); + + if (digits == 4) + sprintf (name, "%svideo/%s/%s0000.pcx", gamedir, base, base); + else + sprintf (name, "%svideo/%s/%s000.pcx", gamedir, base, base); + + printf ("%s\n", name); + Load256Image (name, NULL, &palette, &width, &height); + + output = fopen (savename, "wb"); + if (!output) + Error ("Can't open %s", savename); + + // write header info + i = LittleLong (width); + fwrite (&i, 4, 1, output); + i = LittleLong (height); + fwrite (&i, 4, 1, output); + i = LittleLong (wavinfo.rate); + fwrite (&i, 4, 1, output); + i = LittleLong (wavinfo.width); + fwrite (&i, 4, 1, output); + i = LittleLong (wavinfo.channels); + fwrite (&i, 4, 1, output); + + // build the dictionary + for ( frame=startframe ; ; frame++) + { + printf ("counting ", frame); + in = LoadFrame (base, frame, digits, &palette); + if (!in.data) + break; + Huffman1_Count (in); + free (in.data); + } + printf ("\n"); + + // build nodes and write counts + Huffman1_Build (output); + + + memset (current_palette, 0, sizeof(current_palette)); + + // compress it with the dictionary + for (frame=startframe ; ; frame++) + { + printf ("packing ", frame); + in = LoadFrame (base, frame, digits, &palette); + if (!in.data) + break; + + // see if the palette has changed + for (i=0 ; i<768 ; i++) + if (palette[i] != current_palette[i]) + { + // write a palette change + memcpy (current_palette, palette, sizeof(current_palette)); + command = LittleLong(1); + fwrite (&command, 1, 4, output); + fwrite (current_palette, 1, sizeof(current_palette), output); + break; + } + if (i == 768) + { + command = 0; // no palette change + fwrite (&command, 1, 4, output); + } + + // save the image + huffman = Huffman1 (in); + printf ("%5i bytes after huffman1\n", huffman.count); + + swap = LittleLong (huffman.count); + fwrite (&swap, 1, sizeof(swap), output); + + fwrite (huffman.data, 1, huffman.count, output); + + // save some sound samples + WriteSound (output, frame); + + free (palette); + free (in.data); + free (huffman.data); + } + printf ("\n"); + + // write end-of-file command + command = 2; + fwrite (&command, 1, 4, output); + + printf ("Total size: %i\n", ftell (output)); + + fclose (output); + + if (soundtrack) + free (soundtrack); +} diff --git a/tools/quake2/extra/qe4/brush.c b/tools/quake2/extra/qe4/brush.c new file mode 100644 index 00000000..e8a2b53a --- /dev/null +++ b/tools/quake2/extra/qe4/brush.c @@ -0,0 +1,1568 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include +#include "qe3.h" + +#define MAX_POINTS_ON_WINDING 64 + +face_t *Face_Alloc( void ); +void Face_Free( face_t *f ); + +winding_t *NewWinding (int points); +void FreeWinding (winding_t *w); +winding_t *Winding_Clone( winding_t *w ); +winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon); + +void PrintWinding (winding_t *w) +{ + int i; + + printf ("-------------\n"); + for (i=0 ; inumpoints ; i++) + printf ("(%5.2f, %5.2f, %5.2f)\n", w->points[i][0] + , w->points[i][1], w->points[i][2]); +} + +void PrintPlane (plane_t *p) +{ + printf ("(%5.2f, %5.2f, %5.2f) : %5.2f\n", p->normal[0], p->normal[1], + p->normal[2], p->dist); +} + +void PrintVector (vec3_t v) +{ + printf ("(%5.2f, %5.2f, %5.2f)\n", v[0], v[1], v[2]); +} + + +face_t *Face_Clone (face_t *f) +{ + face_t *n; + + n = Face_Alloc(); + n->texdef = f->texdef; + memcpy (n->planepts, f->planepts, sizeof(n->planepts)); + + // all other fields are derived, and will be set by Brush_Build + return n; +} + +//============================================================================ + +#define BOGUS_RANGE 18000 + + +/* +================== +NewWinding +================== +*/ +winding_t *NewWinding (int points) +{ + winding_t *w; + int size; + + if (points > MAX_POINTS_ON_WINDING) + Error ("NewWinding: %i points", points); + + size = (int)((winding_t *)0)->points[points]; + w = malloc (size); + memset (w, 0, size); + w->maxpoints = points; + + return w; +} + + +void FreeWinding (winding_t *w) +{ + free (w); +} + + +/* +================== +Winding_Clone +================== +*/ +winding_t *Winding_Clone(winding_t *w) +{ + int size; + winding_t *c; + + size = (int)((winding_t *)0)->points[w->numpoints]; + c = qmalloc (size); + memcpy (c, w, size); + return c; +} + + +/* +================== +ClipWinding + +Clips the winding to the plane, returning the new winding on the positive side +Frees the input winding. +If keepon is true, an exactly on-plane winding will be saved, otherwise +it will be clipped away. +================== +*/ +winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon) +{ + vec_t dists[MAX_POINTS_ON_WINDING]; + int sides[MAX_POINTS_ON_WINDING]; + int counts[3]; + vec_t dot; + int i, j; + vec_t *p1, *p2; + vec3_t mid; + winding_t *neww; + int maxpts; + + counts[0] = counts[1] = counts[2] = 0; + +// determine sides for each point + for (i=0 ; inumpoints ; i++) + { + dot = DotProduct (in->points[i], split->normal); + dot -= split->dist; + dists[i] = dot; + if (dot > ON_EPSILON) + sides[i] = SIDE_FRONT; + else if (dot < -ON_EPSILON) + sides[i] = SIDE_BACK; + else + { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + if (keepon && !counts[0] && !counts[1]) + return in; + + if (!counts[0]) + { + FreeWinding (in); + return NULL; + } + if (!counts[1]) + return in; + + maxpts = in->numpoints+4; // can't use counts[0]+2 because + // of fp grouping errors + neww = NewWinding (maxpts); + + for (i=0 ; inumpoints ; i++) + { + p1 = in->points[i]; + + if (sides[i] == SIDE_ON) + { + VectorCopy (p1, neww->points[neww->numpoints]); + neww->numpoints++; + continue; + } + + if (sides[i] == SIDE_FRONT) + { + VectorCopy (p1, neww->points[neww->numpoints]); + neww->numpoints++; + } + + if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + // generate a split point + p2 = in->points[(i+1)%in->numpoints]; + + dot = dists[i] / (dists[i]-dists[i+1]); + for (j=0 ; j<3 ; j++) + { // avoid round off error when possible + if (split->normal[j] == 1) + mid[j] = split->dist; + else if (split->normal[j] == -1) + mid[j] = -split->dist; + else + mid[j] = p1[j] + dot*(p2[j]-p1[j]); + } + + VectorCopy (mid, neww->points[neww->numpoints]); + neww->numpoints++; + } + + if (neww->numpoints > maxpts) + Error ("ClipWinding: points exceeded estimate"); + +// free the original winding + FreeWinding (in); + + return neww; +} + + + +/* +============================================================================= + + TEXTURE COORDINATES + +============================================================================= +*/ + + +/* +================== +textureAxisFromPlane +================== +*/ +vec3_t baseaxis[18] = +{ +{0,0,1}, {1,0,0}, {0,-1,0}, // floor +{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling +{1,0,0}, {0,1,0}, {0,0,-1}, // west wall +{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall +{0,1,0}, {1,0,0}, {0,0,-1}, // south wall +{0,-1,0}, {1,0,0}, {0,0,-1} // north wall +}; + +void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv) +{ + int bestaxis; + float dot,best; + int i; + + best = 0; + bestaxis = 0; + + for (i=0 ; i<6 ; i++) + { + dot = DotProduct (pln->normal, baseaxis[i*3]); + if (dot > best) + { + best = dot; + bestaxis = i; + } + } + + VectorCopy (baseaxis[bestaxis*3+1], xv); + VectorCopy (baseaxis[bestaxis*3+2], yv); +} + + +float lightaxis[3] = {0.6, 0.8, 1.0}; +/* +================ +SetShadeForPlane + +Light different planes differently to +improve recognition +================ +*/ +float SetShadeForPlane (plane_t *p) +{ + int i; + float f; + + // axial plane + for (i=0 ; i<3 ; i++) + if (fabs(p->normal[i]) > 0.9) + { + f = lightaxis[i]; + return f; + } + + // between two axial planes + for (i=0 ; i<3 ; i++) + if (fabs(p->normal[i]) < 0.1) + { + f = (lightaxis[(i+1)%3] + lightaxis[(i+2)%3])/2; + return f; + } + + // other + f= (lightaxis[0] + lightaxis[1] + lightaxis[2]) / 3; + return f; +} + +vec3_t vecs[2]; +float shift[2]; + +/* +================ +BeginTexturingFace +================ +*/ +void BeginTexturingFace (brush_t *b, face_t *f, qtexture_t *q) +{ + vec3_t pvecs[2]; + int sv, tv; + float ang, sinv, cosv; + float ns, nt; + int i,j; + float shade; + + // get natural texture axis + TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]); + + // set shading for face + shade = SetShadeForPlane (&f->plane); + if (camera.draw_mode == cd_texture && !b->owner->eclass->fixedsize) + { + f->d_color[0] = + f->d_color[1] = + f->d_color[2] = shade; + } + else + { + f->d_color[0] = shade*q->color[0]; + f->d_color[1] = shade*q->color[1]; + f->d_color[2] = shade*q->color[2]; + } + + if (camera.draw_mode != cd_texture) + return; + + if (!f->texdef.scale[0]) + f->texdef.scale[0] = 1; + if (!f->texdef.scale[1]) + f->texdef.scale[1] = 1; + + +// rotate axis + if (f->texdef.rotate == 0) + { sinv = 0 ; cosv = 1; } + else if (f->texdef.rotate == 90) + { sinv = 1 ; cosv = 0; } + else if (f->texdef.rotate == 180) + { sinv = 0 ; cosv = -1; } + else if (f->texdef.rotate == 270) + { sinv = -1 ; cosv = 0; } + else + { + ang = f->texdef.rotate / 180 * Q_PI; + sinv = sin(ang); + cosv = cos(ang); + } + + if (pvecs[0][0]) + sv = 0; + else if (pvecs[0][1]) + sv = 1; + else + sv = 2; + + if (pvecs[1][0]) + tv = 0; + else if (pvecs[1][1]) + tv = 1; + else + tv = 2; + + for (i=0 ; i<2 ; i++) + { + ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv]; + nt = sinv * pvecs[i][sv] + cosv * pvecs[i][tv]; + vecs[i][sv] = ns; + vecs[i][tv] = nt; + } + + for (i=0 ; i<2 ; i++) + for (j=0 ; j<3 ; j++) + vecs[i][j] = vecs[i][j] / f->texdef.scale[i]; +} + + +void _EmitTextureCoordinates (vec3_t v, qtexture_t *q) +{ + float s, t; + + s = DotProduct (v, vecs[0]); + t = DotProduct (v, vecs[1]); + + s += shift[0]; + t += shift[1]; + + s /= q->width; + t /= q->height; + + glTexCoord2f (s, t); +} + +void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f) +{ + float s, t, ns, nt; + float ang, sinv, cosv; + vec3_t vecs[2]; + texdef_t *td; + + // get natural texture axis + TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]); + + td = &f->texdef; + + ang = td->rotate / 180 * Q_PI; + sinv = sin(ang); + cosv = cos(ang); + + if (!td->scale[0]) + td->scale[0] = 1; + if (!td->scale[1]) + td->scale[1] = 1; + + s = DotProduct(xyzst, vecs[0]); + t = DotProduct(xyzst, vecs[1]); + + ns = cosv * s - sinv * t; + nt = sinv * s + cosv * t; + + s = ns/td->scale[0] + td->shift[0]; + t = nt/td->scale[1] + td->shift[1]; + + // gl scales everything from 0 to 1 + s /= q->width; + t /= q->height; + + xyzst[3] = s; + xyzst[4] = t; +} + +//========================================================================== + + +/* +================= +BasePolyForPlane +================= +*/ +winding_t *BasePolyForPlane (plane_t *p) +{ + int i, x; + vec_t max, v; + vec3_t org, vright, vup; + winding_t *w; + +// find the major axis + + max = -BOGUS_RANGE; + x = -1; + for (i=0 ; i<3; i++) + { + v = fabs(p->normal[i]); + if (v > max) + { + x = i; + max = v; + } + } + if (x==-1) + Error ("BasePolyForPlane: no axis found"); + + VectorCopy (vec3_origin, vup); + switch (x) + { + case 0: + case 1: + vup[2] = 1; + break; + case 2: + vup[0] = 1; + break; + } + + + v = DotProduct (vup, p->normal); + VectorMA (vup, -v, p->normal, vup); + VectorNormalize (vup); + + VectorScale (p->normal, p->dist, org); + + CrossProduct (vup, p->normal, vright); + + VectorScale (vup, 8192, vup); + VectorScale (vright, 8192, vright); + +// project a really big axis aligned box onto the plane + w = NewWinding (4); + + VectorSubtract (org, vright, w->points[0]); + VectorAdd (w->points[0], vup, w->points[0]); + + VectorAdd (org, vright, w->points[1]); + VectorAdd (w->points[1], vup, w->points[1]); + + VectorAdd (org, vright, w->points[2]); + VectorSubtract (w->points[2], vup, w->points[2]); + + VectorSubtract (org, vright, w->points[3]); + VectorSubtract (w->points[3], vup, w->points[3]); + + w->numpoints = 4; + + return w; +} + +void Brush_MakeFacePlanes (brush_t *b) +{ + face_t *f; + int j; + vec3_t t1, t2, t3; + + for (f=b->brush_faces ; f ; f=f->next) + { + // convert to a vector / dist plane + for (j=0 ; j<3 ; j++) + { + t1[j] = f->planepts[0][j] - f->planepts[1][j]; + t2[j] = f->planepts[2][j] - f->planepts[1][j]; + t3[j] = f->planepts[1][j]; + } + + CrossProduct(t1,t2, f->plane.normal); + if (VectorCompare (f->plane.normal, vec3_origin)) + printf ("WARNING: brush plane with no normal\n"); + VectorNormalize (f->plane.normal); + f->plane.dist = DotProduct (t3, f->plane.normal); + } +} + +void DrawBrushEntityName (brush_t *b) +{ + char *name; + float a, s, c; + vec3_t mid; + int i; + + if (!b->owner) + return; // during contruction + + if (b->owner == world_entity) + return; + + if (b != b->owner->brushes.onext) + return; // not key brush + + // draw the angle pointer + a = FloatForKey (b->owner, "angle"); + if (a) + { + s = sin (a/180*Q_PI); + c = cos (a/180*Q_PI); + for (i=0 ; i<3 ; i++) + mid[i] = (b->mins[i] + b->maxs[i])*0.5; + + glBegin (GL_LINE_STRIP); + glVertex3fv (mid); + mid[0] += c*8; + mid[1] += s*8; + glVertex3fv (mid); + mid[0] -= c*4; + mid[1] -= s*4; + mid[0] -= s*4; + mid[1] += c*4; + glVertex3fv (mid); + mid[0] += c*4; + mid[1] += s*4; + mid[0] += s*4; + mid[1] -= c*4; + glVertex3fv (mid); + mid[0] -= c*4; + mid[1] -= s*4; + mid[0] += s*4; + mid[1] -= c*4; + glVertex3fv (mid); + glEnd (); + } + + if (!g_qeglobals.d_savedinfo.show_names) + return; + + name = ValueForKey (b->owner, "classname"); + glRasterPos2f (b->mins[0]+4, b->mins[1]+4); + glCallLists (strlen(name), GL_UNSIGNED_BYTE, name); +} + +/* +================= +MakeFaceWinding + +returns the visible polygon on a face +================= +*/ +winding_t *MakeFaceWinding (brush_t *b, face_t *face) +{ + winding_t *w; + face_t *clip; + plane_t plane; + qboolean past; + + // get a poly that covers an effectively infinite area + w = BasePolyForPlane (&face->plane); + + // chop the poly by all of the other faces + past = false; + for (clip = b->brush_faces ; clip && w ; clip=clip->next) + { + if (clip == face) + { + past = true; + continue; + } + if (DotProduct (face->plane.normal, clip->plane.normal) > 0.999 + && fabs(face->plane.dist - clip->plane.dist) < 0.01 ) + { // identical plane, use the later one + if (past) + { + free (w); + return NULL; + } + continue; + } + + // flip the plane, because we want to keep the back side + VectorSubtract (vec3_origin,clip->plane.normal, plane.normal); + plane.dist = -clip->plane.dist; + + w = ClipWinding (w, &plane, false); + if (!w) + return w; + } + + if (w->numpoints < 3) + { + free(w); + w = NULL; + } + + if (!w) + printf ("unused plane\n"); + + return w; +} + + +void Brush_SnapPlanepts (brush_t *b) +{ + int i, j; + face_t *f; + + for (f=b->brush_faces ; f; f=f->next) + for (i=0 ; i<3 ; i++) + for (j=0 ; j<3 ; j++) + f->planepts[i][j] = floor (f->planepts[i][j] + 0.5); +} + +/* +** Brush_Build +** +** Builds a brush rendering data and also sets the min/max bounds +*/ +#define ZERO_EPSILON 0.001 +void Brush_Build( brush_t *b ) +{ +// int order; +// face_t *face; +// winding_t *w; + char title[1024]; + + if (modified != 1) + { + modified = true; // mark the map as changed + sprintf (title, "%s *", currentmap); + + QE_ConvertDOSToUnixName( title, title ); + Sys_SetTitle (title); + } + + /* + ** build the windings and generate the bounding box + */ + Brush_BuildWindings( b ); + + /* + ** move the points and edges if in select mode + */ + if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge) + SetupVertexSelection (); +} + +/* +================= +Brush_Parse + +The brush is NOT linked to any list +================= +*/ +brush_t *Brush_Parse (void) +{ + brush_t *b; + face_t *f; + int i,j; + + g_qeglobals.d_parsed_brushes++; + b = qmalloc(sizeof(brush_t)); + + do + { + if (!GetToken (true)) + break; + if (!strcmp (token, "}") ) + break; + + f = Face_Alloc(); + + // add the brush to the end of the chain, so + // loading and saving a map doesn't reverse the order + + f->next = NULL; + if (!b->brush_faces) + { + b->brush_faces = f; + } + else + { + face_t *scan; + + for (scan=b->brush_faces ; scan->next ; scan=scan->next) + ; + scan->next = f; + } + + // read the three point plane definition + for (i=0 ; i<3 ; i++) + { + if (i != 0) + GetToken (true); + if (strcmp (token, "(") ) + Error ("parsing brush"); + + for (j=0 ; j<3 ; j++) + { + GetToken (false); + f->planepts[i][j] = atoi(token); + } + + GetToken (false); + if (strcmp (token, ")") ) + Error ("parsing brush"); + + } + + // read the texturedef + GetToken (false); + strcpy(f->texdef.name, token); + GetToken (false); + f->texdef.shift[0] = atoi(token); + GetToken (false); + f->texdef.shift[1] = atoi(token); + GetToken (false); + f->texdef.rotate = atoi(token); + GetToken (false); + f->texdef.scale[0] = atof(token); + GetToken (false); + f->texdef.scale[1] = atof(token); + + // the flags and value field aren't necessarily present + f->d_texture = Texture_ForName( f->texdef.name ); + f->texdef.flags = f->d_texture->flags; + f->texdef.value = f->d_texture->value; + f->texdef.contents = f->d_texture->contents; + + if (TokenAvailable ()) + { + GetToken (false); + f->texdef.contents = atoi(token); + GetToken (false); + f->texdef.flags = atoi(token); + GetToken (false); + f->texdef.value = atoi(token); + } + } while (1); + + return b; +} + +/* +================= +Brush_Write +================= +*/ +void Brush_Write (brush_t *b, FILE *f) +{ + face_t *fa; + char *pname; + int i; + + fprintf (f, "{\n"); + for (fa=b->brush_faces ; fa ; fa=fa->next) + { + for (i=0 ; i<3 ; i++) + fprintf (f, "( %i %i %i ) ", (int)fa->planepts[i][0] + , (int)fa->planepts[i][1], (int)fa->planepts[i][2]); + + pname = fa->texdef.name; + if (pname[0] == 0) + pname = "unnamed"; + + fprintf (f, "%s %i %i %i ", pname, + (int)fa->texdef.shift[0], (int)fa->texdef.shift[1], + (int)fa->texdef.rotate); + + if (fa->texdef.scale[0] == (int)fa->texdef.scale[0]) + fprintf (f, "%i ", (int)fa->texdef.scale[0]); + else + fprintf (f, "%f ", (float)fa->texdef.scale[0]); + if (fa->texdef.scale[1] == (int)fa->texdef.scale[1]) + fprintf (f, "%i", (int)fa->texdef.scale[1]); + else + fprintf (f, "%f", (float)fa->texdef.scale[1]); + + // only output flags and value if not default + if (fa->texdef.value != fa->d_texture->value + || fa->texdef.flags != fa->d_texture->flags + || fa->texdef.contents != fa->d_texture->contents) + { + fprintf (f, " %i %i %i", fa->texdef.contents, fa->texdef.flags, fa->texdef.value); + } + + fprintf (f, "\n"); + } + fprintf (f, "}\n"); +} + + +/* +============= +Brush_Create + +Create non-textured blocks for entities +The brush is NOT linked to any list +============= +*/ +brush_t *Brush_Create (vec3_t mins, vec3_t maxs, texdef_t *texdef) +{ + int i, j; + vec3_t pts[4][2]; + face_t *f; + brush_t *b; + + for (i=0 ; i<3 ; i++) + if (maxs[i] < mins[i]) + Error ("Brush_InitSolid: backwards"); + + b = qmalloc (sizeof(brush_t)); + + pts[0][0][0] = mins[0]; + pts[0][0][1] = mins[1]; + + pts[1][0][0] = mins[0]; + pts[1][0][1] = maxs[1]; + + pts[2][0][0] = maxs[0]; + pts[2][0][1] = maxs[1]; + + pts[3][0][0] = maxs[0]; + pts[3][0][1] = mins[1]; + + for (i=0 ; i<4 ; i++) + { + pts[i][0][2] = mins[2]; + pts[i][1][0] = pts[i][0][0]; + pts[i][1][1] = pts[i][0][1]; + pts[i][1][2] = maxs[2]; + } + + for (i=0 ; i<4 ; i++) + { + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + j = (i+1)%4; + + VectorCopy (pts[j][1], f->planepts[0]); + VectorCopy (pts[i][1], f->planepts[1]); + VectorCopy (pts[i][0], f->planepts[2]); + } + + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy (pts[0][1], f->planepts[0]); + VectorCopy (pts[1][1], f->planepts[1]); + VectorCopy (pts[2][1], f->planepts[2]); + + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + VectorCopy (pts[2][0], f->planepts[0]); + VectorCopy (pts[1][0], f->planepts[1]); + VectorCopy (pts[0][0], f->planepts[2]); + + return b; +} + + +/* +============= +Brush_MakeSided + +Makes the current brushhave the given number of 2d sides +============= +*/ +void Brush_MakeSided (int sides) +{ + int i; + vec3_t mins, maxs; + brush_t *b; + texdef_t *texdef; + face_t *f; + vec3_t mid; + float width; + float sv, cv; + + if (sides < 3) + { + Sys_Status ("Bad sides number", 0); + return; + } + + if (!QE_SingleBrush ()) + { + Sys_Status ("Must have a single brush selected", 0 ); + return; + } + + b = selected_brushes.next; + VectorCopy (b->mins, mins); + VectorCopy (b->maxs, maxs); + texdef = &g_qeglobals.d_texturewin.texdef; + + Brush_Free (b); + + // find center of brush + width = 8; + for (i=0 ; i<2 ; i++) + { + mid[i] = (maxs[i] + mins[i])*0.5; + if (maxs[i] - mins[i] > width) + width = maxs[i] - mins[i]; + } + width /= 2; + + b = qmalloc (sizeof(brush_t)); + + // create top face + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + +f->planepts[2][0] = mins[0];f->planepts[2][1] = mins[1];f->planepts[2][2] = maxs[2]; +f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = maxs[2]; +f->planepts[0][0] = maxs[0];f->planepts[0][1] = maxs[1];f->planepts[0][2] = maxs[2]; + + // create bottom face + f = Face_Alloc(); + f->texdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + +f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2]; +f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2]; +f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2]; + + for (i=0 ; itexdef = *texdef; + f->next = b->brush_faces; + b->brush_faces = f; + + sv = sin (i*3.14159265*2/sides); + cv = cos (i*3.14159265*2/sides); + + f->planepts[0][0] = floor(mid[0]+width*cv+0.5); + f->planepts[0][1] = floor(mid[1]+width*sv+0.5); + f->planepts[0][2] = mins[2]; + + f->planepts[1][0] = f->planepts[0][0]; + f->planepts[1][1] = f->planepts[0][1]; + f->planepts[1][2] = maxs[2]; + + f->planepts[2][0] = floor(f->planepts[0][0] - width*sv + 0.5); + f->planepts[2][1] = floor(f->planepts[0][1] + width*cv + 0.5); + f->planepts[2][2] = maxs[2]; + + } + + Brush_AddToList (b, &selected_brushes); + + Entity_LinkBrush (world_entity, b); + + Brush_Build( b ); + + Sys_UpdateWindows (W_ALL); +} + + +/* +============= +Brush_Free + +Frees the brush with all of its faces and display list. +Unlinks the brush from whichever chain it is in. +Decrements the owner entity's brushcount. +Removes owner entity if this was the last brush +unless owner is the world. +============= +*/ +void Brush_Free (brush_t *b) +{ + face_t *f, *next; + + // free faces + for (f=b->brush_faces ; f ; f=next) + { + next = f->next; + Face_Free( f ); + } + + /* + for ( i = 0; i < b->d_numwindings; i++ ) + { + if ( b->d_windings[i] ) + { + FreeWinding( b->d_windings[i] ); + b->d_windings[i] = 0; + } + } + */ + + // unlink from active/selected list + if (b->next) + Brush_RemoveFromList (b); + + // unlink from entity list + if (b->onext) + Entity_UnlinkBrush (b); + + free (b); +} + +/* +============ +Brush_Move +============ +*/ +void Brush_Move (brush_t *b, vec3_t move) +{ + int i; + face_t *f; + + for (f=b->brush_faces ; f ; f=f->next) + for (i=0 ; i<3 ; i++) + VectorAdd (f->planepts[i], move, f->planepts[i]); + Brush_Build( b ); +} + +/* +============ +Brush_Clone + +Does NOT add the new brush to any lists +============ +*/ +brush_t *Brush_Clone (brush_t *b) +{ + brush_t *n; + face_t *f, *nf; + + n = qmalloc(sizeof(brush_t)); + n->owner = b->owner; + for (f=b->brush_faces ; f ; f=f->next) + { + nf = Face_Clone( f ); + nf->next = n->brush_faces; + n->brush_faces = nf; + } + return n; +} + +/* +============== +Brush_Ray + +Itersects a ray with a brush +Returns the face hit and the distance along the ray the intersection occured at +Returns NULL and 0 if not hit at all +============== +*/ +face_t *Brush_Ray (vec3_t origin, vec3_t dir, brush_t *b, float *dist) +{ + face_t *f, *firstface; + vec3_t p1, p2; + float frac, d1, d2; + int i; + + VectorCopy (origin, p1); + for (i=0 ; i<3 ; i++) + p2[i] = p1[i] + dir[i]*16384; + + for (f=b->brush_faces ; f ; f=f->next) + { + d1 = DotProduct (p1, f->plane.normal) - f->plane.dist; + d2 = DotProduct (p2, f->plane.normal) - f->plane.dist; + if (d1 >= 0 && d2 >= 0) + { + *dist = 0; + return NULL; // ray is on front side of face + } + if (d1 <=0 && d2 <= 0) + continue; + // clip the ray to the plane + frac = d1 / (d1 - d2); + if (d1 > 0) + { + firstface = f; + for (i=0 ; i<3 ; i++) + p1[i] = p1[i] + frac *(p2[i] - p1[i]); + } + else + { + for (i=0 ; i<3 ; i++) + p2[i] = p1[i] + frac *(p2[i] - p1[i]); + } + } + + // find distance p1 is along dir + VectorSubtract (p1, origin, p1); + d1 = DotProduct (p1, dir); + + *dist = d1; + + return firstface; +} + +void Brush_AddToList (brush_t *b, brush_t *list) +{ + if (b->next || b->prev) + Error ("Brush_RemoveFromList: allready linked"); + b->next = list->next; + list->next->prev = b; + list->next = b; + b->prev = list; +} + +void Brush_RemoveFromList (brush_t *b) +{ + if (!b->next || !b->prev) + Error ("Brush_RemoveFromList: not linked"); + b->next->prev = b->prev; + b->prev->next = b->next; + b->next = b->prev = NULL; +} + +void Brush_SetTexture (brush_t *b, texdef_t *texdef) +{ + face_t *f; + + for (f=b->brush_faces ; f ; f=f->next) + f->texdef = *texdef; + Brush_Build( b ); +} + + +qboolean ClipLineToFace (vec3_t p1, vec3_t p2, face_t *f) +{ + float d1, d2, fr; + int i; + float *v; + + d1 = DotProduct (p1, f->plane.normal) - f->plane.dist; + d2 = DotProduct (p2, f->plane.normal) - f->plane.dist; + + if (d1 >= 0 && d2 >= 0) + return false; // totally outside + if (d1 <= 0 && d2 <= 0) + return true; // totally inside + + fr = d1 / (d1 - d2); + + if (d1 > 0) + v = p1; + else + v = p2; + + for (i=0 ; i<3 ; i++) + v[i] = p1[i] + fr*(p2[i] - p1[i]); + + return true; +} + + +int AddPlanept (float *f) +{ + int i; + + for (i=0 ; iowner->eclass->fixedsize) + return; + + c = 0; + for (i=0 ; i<3 ; i++) + c += AddPlanept (f->planepts[i]); + if (c == 0) + return; // allready completely added + + // select all points on this plane in all brushes the selection + for (b2=selected_brushes.next ; b2 != &selected_brushes ; b2 = b2->next) + { + if (b2 == b) + continue; + for (f2=b2->brush_faces ; f2 ; f2=f2->next) + { + for (i=0 ; i<3 ; i++) + if (fabs(DotProduct(f2->planepts[i], f->plane.normal) + -f->plane.dist) > ON_EPSILON) + break; + if (i==3) + { // move this face as well + Brush_SelectFaceForDragging (b2, f2, shear); + break; + } + } + } + + + // if shearing, take all the planes adjacent to + // selected faces and rotate their points so the + // edge clipped by a selcted face has two of the points + if (!shear) + return; + + for (f2=b->brush_faces ; f2 ; f2=f2->next) + { + if (f2 == f) + continue; + w = MakeFaceWinding (b, f2); + if (!w) + continue; + + // any points on f will become new control points + for (i=0 ; inumpoints ; i++) + { + d = DotProduct (w->points[i], f->plane.normal) + - f->plane.dist; + if (d > -ON_EPSILON && d < ON_EPSILON) + break; + } + + // + // if none of the points were on the plane, + // leave it alone + // + if (i != w->numpoints) + { + if (i == 0) + { // see if the first clockwise point was the + // last point on the winding + d = DotProduct (w->points[w->numpoints-1] + , f->plane.normal) - f->plane.dist; + if (d > -ON_EPSILON && d < ON_EPSILON) + i = w->numpoints - 1; + } + + AddPlanept (f2->planepts[0]); + + VectorCopy (w->points[i], f2->planepts[0]); + if (++i == w->numpoints) + i = 0; + + // see if the next point is also on the plane + d = DotProduct (w->points[i] + , f->plane.normal) - f->plane.dist; + if (d > -ON_EPSILON && d < ON_EPSILON) + AddPlanept (f2->planepts[1]); + + VectorCopy (w->points[i], f2->planepts[1]); + if (++i == w->numpoints) + i = 0; + + // the third point is never on the plane + + VectorCopy (w->points[i], f2->planepts[2]); + } + + free(w); + } +} + +/* +============== +Brush_SideSelect + +The mouse click did not hit the brush, so grab one or more side +planes for dragging +============== +*/ +void Brush_SideSelect (brush_t *b, vec3_t origin, vec3_t dir + , qboolean shear) +{ + face_t *f, *f2; + vec3_t p1, p2; + + for (f=b->brush_faces ; f ; f=f->next) + { + VectorCopy (origin, p1); + VectorMA (origin, 16384, dir, p2); + + for (f2=b->brush_faces ; f2 ; f2=f2->next) + { + if (f2 == f) + continue; + ClipLineToFace (p1, p2, f2); + } + + if (f2) + continue; + + if (VectorCompare (p1, origin)) + continue; + if (ClipLineToFace (p1, p2, f)) + continue; + + Brush_SelectFaceForDragging (b, f, shear); + } + + +} + +void Brush_BuildWindings( brush_t *b ) +{ + winding_t *w; + face_t *face; + vec_t v; + + Brush_SnapPlanepts( b ); + + // clear the mins/maxs bounds + b->mins[0] = b->mins[1] = b->mins[2] = 99999; + b->maxs[0] = b->maxs[1] = b->maxs[2] = -99999; + + Brush_MakeFacePlanes (b); + + face = b->brush_faces; + + for ( ; face ; face=face->next) + { + int i, j; + + w = face->face_winding = MakeFaceWinding (b, face); + face->d_texture = Texture_ForName( face->texdef.name ); + + if (!w) + { + continue; + } + + for (i=0 ; inumpoints ; i++) + { + // add to bounding box + for (j=0 ; j<3 ; j++) + { + v = w->points[i][j]; + if (v > b->maxs[j]) + b->maxs[j] = v; + if (v < b->mins[j]) + b->mins[j] = v; + } + } + // setup s and t vectors, and set color + BeginTexturingFace( b, face, face->d_texture); + + + for (i=0 ; inumpoints ; i++) + { + EmitTextureCoordinates( w->points[i], face->d_texture, face); + } + } +} + +/* +================== +Brush_RemoveEmptyFaces + +Frees any overconstraining faces +================== +*/ +void Brush_RemoveEmptyFaces ( brush_t *b ) +{ + face_t *f, *next; + + f = b->brush_faces; + b->brush_faces = NULL; + + for ( ; f ; f=next) + { + next = f->next; + if (!f->face_winding) + Face_Free (f); + else + { + f->next = b->brush_faces; + b->brush_faces = f; + } + + } +} + +void Brush_Draw( brush_t *b ) +{ + face_t *face; + int i, order; + qtexture_t *prev = 0; + winding_t *w; + + if (b->owner->eclass->fixedsize && camera.draw_mode == cd_texture) + glDisable (GL_TEXTURE_2D); + + // guarantee the texture will be set first + prev = NULL; + for (face = b->brush_faces,order = 0 ; face ; face=face->next, order++) + { + w = face->face_winding; + if (!w) + continue; // freed face + + if ( face->d_texture != prev && camera.draw_mode == cd_texture) + { + // set the texture for this face + prev = face->d_texture; + glBindTexture( GL_TEXTURE_2D, face->d_texture->texture_number ); + } + + glColor3fv( face->d_color ); + + // draw the polygon + glBegin(GL_POLYGON); + for (i=0 ; inumpoints ; i++) + { + if (camera.draw_mode == cd_texture) + glTexCoord2fv( &w->points[i][3] ); + glVertex3fv(w->points[i]); + } + glEnd(); + } + + if (b->owner->eclass->fixedsize && camera.draw_mode == cd_texture) + glEnable (GL_TEXTURE_2D); + + glBindTexture( GL_TEXTURE_2D, 0 ); +} + +void Face_Draw( face_t *f ) +{ + int i; + + if ( f->face_winding == 0 ) + return; + glBegin( GL_POLYGON ); + for ( i = 0 ; i < f->face_winding->numpoints; i++) + glVertex3fv( f->face_winding->points[i] ); + glEnd(); +} + +void Brush_DrawXY( brush_t *b ) +{ + face_t *face; + int order; + winding_t *w; + int i; + + for (face = b->brush_faces,order = 0 ; face ; face=face->next, order++) + { + // only draw up facing polygons + if (face->plane.normal[2] <= 0) + continue; + + w = face->face_winding; + if (!w) + continue; + + // draw the polygon + glBegin(GL_LINE_LOOP); + for (i=0 ; inumpoints ; i++) + glVertex3fv(w->points[i]); + glEnd(); + } + + // optionally add a text label + if ( g_qeglobals.d_savedinfo.show_names ) + DrawBrushEntityName (b); +} + +face_t *Face_Alloc( void ) +{ + face_t *f = qmalloc( sizeof( *f ) ); + + return f; +} + +void Face_Free( face_t *f ) +{ + assert( f != 0 ); + + if ( f->face_winding ) + free( f->face_winding ), f->face_winding = 0; + free( f ); +} diff --git a/tools/quake2/extra/qe4/brush.h b/tools/quake2/extra/qe4/brush.h new file mode 100644 index 00000000..7a948e03 --- /dev/null +++ b/tools/quake2/extra/qe4/brush.h @@ -0,0 +1,87 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// brush.h + + +typedef struct +{ + int numpoints; + int maxpoints; + float points[8][5]; // variable sized +} winding_t; + + +// the normals on planes point OUT of the brush +#define MAXPOINTS 16 +typedef struct face_s +{ + struct face_s *next; + vec3_t planepts[3]; + texdef_t texdef; + + plane_t plane; + + winding_t *face_winding; + + vec3_t d_color; + qtexture_t *d_texture; + +// int d_numpoints; +// vec3_t *d_points; +} face_t; + +#define MAX_FACES 16 +typedef struct brush_s +{ + struct brush_s *prev, *next; // links in active/selected + struct brush_s *oprev, *onext; // links in entity + struct entity_s *owner; + vec3_t mins, maxs; + + face_t *brush_faces; +} brush_t; + + +void Brush_AddToList (brush_t *b, brush_t *list); +void Brush_Build(brush_t *b); +void Brush_BuildWindings( brush_t *b ); +brush_t *Brush_Clone (brush_t *b); +brush_t *Brush_Create (vec3_t mins, vec3_t maxs, texdef_t *texdef); +void Brush_Draw( brush_t *b ); +void Brush_DrawXY( brush_t *b ); +void Brush_Free (brush_t *b); +void Brush_MakeSided (int sides); +void Brush_Move (brush_t *b, vec3_t move); +brush_t *Brush_Parse (void); +face_t *Brush_Ray (vec3_t origin, vec3_t dir, brush_t *b, float *dist); +void Brush_RemoveFromList (brush_t *b); +void Brush_SelectFaceForDragging (brush_t *b, face_t *f, qboolean shear); +void Brush_SetTexture (brush_t *b, texdef_t *texdef); +void Brush_SideSelect (brush_t *b, vec3_t origin, vec3_t dir, qboolean shear); +void Brush_Write (brush_t *b, FILE *f); +void Brush_RemoveEmptyFaces ( brush_t *b ); + +int AddPlanept (float *f); +face_t *Face_Clone (face_t *f); +void Face_Draw( face_t *face ); +winding_t *MakeFaceWinding (brush_t *b, face_t *face); diff --git a/tools/quake2/extra/qe4/bspfile.h b/tools/quake2/extra/qe4/bspfile.h new file mode 100644 index 00000000..89c56a34 --- /dev/null +++ b/tools/quake2/extra/qe4/bspfile.h @@ -0,0 +1,378 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// upper design bounds +// leaffaces, leafbrushes, planes, and verts are still bounded by +// 16 bit short limits +#define MAX_MAP_MODELS 1024 +#define MAX_MAP_BRUSHES 8192 +#define MAX_MAP_ENTITIES 2048 +#define MAX_MAP_PATHS 2048 +#define MAX_MAP_ENTSTRING 0x20000 +#define MAX_MAP_TEXTURES 1024 +#define MAX_MAP_TEXINFO 8192 + +#define MAX_MAP_PLANES 65536 +#define MAX_MAP_NODES 65536 +#define MAX_MAP_BRUSHSIDES 65536 +#define MAX_MAP_LEAFS 65536 +#define MAX_MAP_VERTS 65536 +#define MAX_MAP_FACES 65536 +#define MAX_MAP_LEAFFACES 65536 +#define MAX_MAP_LEAFBRUSHES 65536 +#define MAX_MAP_PORTALS 65536 +#define MAX_MAP_EDGES 128000 +#define MAX_MAP_SURFEDGES 256000 +#define MAX_MAP_MIPTEX 0x200000 +#define MAX_MAP_LIGHTING 0x200000 +#define MAX_MAP_VISIBILITY 0x100000 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + +//============================================================================= + +#define BSPVERSION 34 + +typedef struct +{ + int fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_PLANES 1 +#define LUMP_TEXTURES 2 +#define LUMP_VERTEXES 3 +#define LUMP_VISIBILITY 4 +#define LUMP_NODES 5 +#define LUMP_TEXINFO 6 +#define LUMP_FACES 7 +#define LUMP_LIGHTING 8 +#define LUMP_LEAFS 9 +#define LUMP_LEAFFACES 10 +#define LUMP_LEAFBRUSHES 11 +#define LUMP_EDGES 12 +#define LUMP_SURFEDGES 13 +#define LUMP_MODELS 14 +#define LUMP_PATHS 15 +#define LUMP_BRUSHES 16 +#define LUMP_BRUSHSIDES 17 +#define LUMP_POP 18 + +#define HEADER_LUMPS 18 + +typedef struct +{ + int version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; // for sounds or lights + int headnode; + int visleafs; // not including the solid leaf 0 + int firstface, numfaces; +} dmodel_t; + +typedef struct +{ + int nummiptex; + int dataofs[4]; // [nummiptex] +} dmiptexlump_t; + +#define MIPLEVELS 4 +typedef struct miptex_s +{ + char name[16]; + unsigned width, height; + unsigned offsets[MIPLEVELS]; // four mip maps stored + int flags; + int value; +} miptex_t; + + +typedef struct +{ + float point[3]; +} dvertex_t; + + +// 0-2 are axial planes +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +// 3-5 are non-axial planes snapped to the nearest +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +// planes (x&~1) and (x&~1)+1 are allways opposites + +typedef struct +{ + float normal[3]; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + + +// contents flags are seperate bits +// a given brush can contribute multiple content bits +// multiple brushes can be in a single leaf + +// lower bits are stronger, and will eat weaker brushes completely +#define CONTENTS_SOLID 1 // an eye is never valid in a solid +#define CONTENTS_WINDOW 2 // translucent, but not watery +#define CONTENTS_LAVA 8 +#define CONTENTS_SLIME 16 +#define CONTENTS_WATER 32 +#define CONTENTS_THINWATER 64 // translucent faces + +#define LAST_VISIBLE_CONTENTS 64 + +// remaining contents are non-visible, and don't eat brushes +#define CONTENTS_MONSTER 128 +#define CONTENTS_PLAYERCLIP 256 +#define CONTENTS_MONSTERCLIP 512 + + +// currents can be added to any other contents, and may be mixed +#define CONTENTS_CURRENT_0 1024 +#define CONTENTS_CURRENT_90 2048 +#define CONTENTS_CURRENT_180 4096 +#define CONTENTS_CURRENT_270 8192 +#define CONTENTS_CURRENT_UP 16384 +#define CONTENTS_CURRENT_DOWN 32768 + +#define CONTENTS_ORIGIN 65536 // removed before processing + + + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + int planenum; + int children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for frustom culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides +} dnode_t; + +typedef struct texinfo_s +{ + float vecs[2][4]; // [s/t][xyz offset] + int miptex; + int flags; // miptex flags + overrides + int value; // light emition, etc +} texinfo_t; + +#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision +#define SURF_LIGHT 2 + +#define SURF_WATER 4 +#define SURF_SLIME 8 +#define SURF_LAVA 16 +#define SURF_WINDOW 32 + +#define SURF_SKY 64 +#define SURF_MIRROR 128 + +#define SURF_SLIPPERY 256 + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +typedef struct +{ + unsigned short v[2]; // vertex numbers +} dedge_t; + +#define MAXLIGHTMAPS 4 +typedef struct +{ + unsigned short planenum; + short side; + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dface_t; + +typedef struct +{ + int contents; // OR of all brushes + int visofs; // -1 = no visibility info + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstleafface; + unsigned short numleaffaces; + + unsigned short firstleafbrush; + unsigned short numleafbrushes; +} dleaf_t; + + +typedef struct +{ + unsigned short planenum; // facing out of the leaf + short texinfo; +} dbrushside_t; + +typedef struct +{ + int firstside; + int numsides; + int contents; +} dbrush_t; + +typedef struct +{ + float origin[3]; + float angles[3]; + int next, prev; + int flags; + float speed; +} dpath_t; + +//============================================================================ + +#ifndef QUAKE_GAME + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +// the utilities get to be lazy and just use large static arrays + +extern int nummodels; +extern dmodel_t dmodels[MAX_MAP_MODELS]; + +extern int visdatasize; +extern byte dvisdata[MAX_MAP_VISIBILITY]; + +extern int lightdatasize; +extern byte dlightdata[MAX_MAP_LIGHTING]; + +extern int texdatasize; +extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t) + +extern int entdatasize; +extern char dentdata[MAX_MAP_ENTSTRING]; + +extern int numleafs; +extern dleaf_t dleafs[MAX_MAP_LEAFS]; + +extern int numplanes; +extern dplane_t dplanes[MAX_MAP_PLANES]; + +extern int numvertexes; +extern dvertex_t dvertexes[MAX_MAP_VERTS]; + +extern int numnodes; +extern dnode_t dnodes[MAX_MAP_NODES]; + +extern int numtexinfo; +extern texinfo_t texinfo[MAX_MAP_TEXINFO]; + +extern int numfaces; +extern dface_t dfaces[MAX_MAP_FACES]; + +extern int numedges; +extern dedge_t dedges[MAX_MAP_EDGES]; + +extern int numleaffaces; +extern unsigned short dleaffaces[MAX_MAP_LEAFFACES]; + +extern int numleafbrushes; +extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES]; + +extern int numsurfedges; +extern int dsurfedges[MAX_MAP_SURFEDGES]; + +extern int numpaths; +extern dpath_t dpaths[MAX_MAP_PATHS]; + +extern int numbrushes; +extern dbrush_t dbrushes[MAX_MAP_BRUSHES]; + +extern int numbrushsides; +extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES]; + + +void DecompressVis (byte *in, byte *decompressed); +int CompressVis (byte *vis, byte *dest); + +void LoadBSPFile (char *filename); +void WriteBSPFile (char *filename); +void PrintBSPFileSizes (void); + +//=============== + + +typedef struct epair_s +{ + struct epair_s *next; + char *key; + char *value; +} epair_t; + +typedef struct +{ + vec3_t origin; + int firstbrush; + int numbrushes; + epair_t *epairs; +} entity_t; + +extern int num_entities; +extern entity_t entities[MAX_MAP_ENTITIES]; + +void ParseEntities (void); +void UnparseEntities (void); + +void SetKeyValue (entity_t *ent, char *key, char *value); +char *ValueForKey (entity_t *ent, char *key); +// will return "" if not present + +vec_t FloatForKey (entity_t *ent, char *key); +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec); + +epair_t *ParseEpair (void); + +void PrintEntity (entity_t *ent); + +extern int r_leaftovis[MAX_MAP_LEAFS]; +extern int r_vistoleaf[MAX_MAP_LEAFS]; +extern int r_numvisleafs; + +#endif diff --git a/tools/quake2/extra/qe4/camera.c b/tools/quake2/extra/qe4/camera.c new file mode 100644 index 00000000..8dd7d5f5 --- /dev/null +++ b/tools/quake2/extra/qe4/camera.c @@ -0,0 +1,594 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +#define PAGEFLIPS 2 + +void DrawPathLines (void); + +camera_t camera; + +/* +============ +Cam_Init +============ +*/ +void Cam_Init (void) +{ +// camera.draw_mode = cd_texture; +// camera.draw_mode = cd_solid; +// camera.draw_mode = cd_wire; + + camera.timing = false; + + camera.origin[0] = 0; + camera.origin[1] = 20; + camera.origin[2] = 46; + + camera.color[0] = 0.3; + camera.color[1] = 0.3; + camera.color[2] = 0.3; +} + + +//============================================================================ + +void Cam_BuildMatrix (void) +{ + float xa, ya; + float matrix[4][4]; + int i; + + xa = camera.angles[0]/180*Q_PI; + ya = camera.angles[1]/180*Q_PI; + + // the movement matrix is kept 2d + + camera.forward[0] = cos(ya); + camera.forward[1] = sin(ya); + camera.right[0] = camera.forward[1]; + camera.right[1] = -camera.forward[0]; + + glGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]); + + for (i=0 ; i<3 ; i++) + { + camera.vright[i] = matrix[i][0]; + camera.vup[i] = matrix[i][1]; + camera.vpn[i] = matrix[i][2]; + } + + VectorNormalize (camera.vright); + VectorNormalize (camera.vup); + VectorNormalize (camera.vpn); +} + +//=============================================== + +/* +=============== +Cam_ChangeFloor +=============== +*/ +void Cam_ChangeFloor (qboolean up) +{ + brush_t *b; + float d, bestd, current; + vec3_t start, dir; + + start[0] = camera.origin[0]; + start[1] = camera.origin[1]; + start[2] = 8192; + dir[0] = dir[1] = 0; + dir[2] = -1; + + current = 8192 - (camera.origin[2] - 48); + if (up) + bestd = 0; + else + bestd = 16384; + + for (b=active_brushes.next ; b != &active_brushes ; b=b->next) + { + if (!Brush_Ray (start, dir, b, &d)) + continue; + if (up && d < current && d > bestd) + bestd = d; + if (!up && d > current && d < bestd) + bestd = d; + } + + if (bestd == 0 || bestd == 16384) + return; + + camera.origin[2] += current - bestd; + Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY); +} + + +//=============================================== + +int cambuttonstate; +static int buttonx, buttony; +static int cursorx, cursory; + +face_t *side_select; + +#define ANGLE_SPEED 300 +#define MOVE_SPEED 400 + +/* +================ +Cam_PositionDrag +================ +*/ +void Cam_PositionDrag (void) +{ + int x, y; + + Sys_GetCursorPos (&x, &y); + if (x != cursorx || y != cursory) + { + x -= cursorx; + VectorMA (camera.origin, x, camera.vright, camera.origin); + y -= cursory; + camera.origin[2] -= y; + + Sys_SetCursorPos (cursorx, cursory); + Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY); + } +} + +/* +=============== +Cam_MouseControl +=============== +*/ +void Cam_MouseControl (float dtime) +{ + int xl, xh; + int yl, yh; + float xf, yf; + + if (cambuttonstate != MK_RBUTTON) + return; + + xf = (float)(buttonx - camera.width/2) / (camera.width/2); + yf = (float)(buttony - camera.height/2) / (camera.height/2); + + xl = camera.width/3; + xh = xl*2; + yl = camera.height/3; + yh = yl*2; + +#if 0 + // strafe + if (buttony < yl && (buttonx < xl || buttonx > xh)) + VectorMA (camera.origin, xf*dtime*MOVE_SPEED, camera.right, camera.origin); + else +#endif + { + xf *= 1.0 - fabs(yf); + if (xf < 0) + { + xf += 0.1; + if (xf > 0) + xf = 0; + } + else + { + xf -= 0.1; + if (xf < 0) + xf = 0; + } + + VectorMA (camera.origin, yf*dtime*MOVE_SPEED, camera.forward, camera.origin); + camera.angles[YAW] += xf*-dtime*ANGLE_SPEED; + } + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); +} + + + + +/* +============== +Cam_MouseDown +============== +*/ +void Cam_MouseDown (int x, int y, int buttons) +{ + vec3_t dir; + float f, r, u; + int i; + + // + // calc ray direction + // + u = (float)(y - camera.height/2) / (camera.width/2); + r = (float)(x - camera.width/2) / (camera.width/2); + f = 1; + + for (i=0 ; i<3 ; i++) + dir[i] = camera.vpn[i] * f + camera.vright[i] * r + camera.vup[i] * u; + VectorNormalize (dir); + + Sys_GetCursorPos (&cursorx, &cursory); + + cambuttonstate = buttons; + buttonx = x; + buttony = y; + + // LBUTTON = manipulate selection + // shift-LBUTTON = select + // middle button = grab texture + // ctrl-middle button = set entire brush to texture + // ctrl-shift-middle button = set single face to texture + if ( (buttons == MK_LBUTTON) + || (buttons == (MK_LBUTTON | MK_SHIFT)) + || (buttons == (MK_LBUTTON | MK_CONTROL)) + || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) + || (buttons == MK_MBUTTON) + || (buttons == (MK_MBUTTON|MK_CONTROL)) + || (buttons == (MK_MBUTTON|MK_SHIFT|MK_CONTROL)) ) + { + Drag_Begin (x, y, buttons, + camera.vright, camera.vup, + camera.origin, dir); + return; + } + + if (buttons == MK_RBUTTON) + { + Cam_MouseControl (0.1); + return; + } +} + +/* +============== +Cam_MouseUp +============== +*/ +void Cam_MouseUp (int x, int y, int buttons) +{ + cambuttonstate = 0; + Drag_MouseUp (); +} + + +/* +============== +Cam_MouseMoved +============== +*/ +void Cam_MouseMoved (int x, int y, int buttons) +{ + cambuttonstate = buttons; + if (!buttons) + return; + buttonx = x; + buttony = y; + + if (buttons == (MK_RBUTTON|MK_CONTROL) ) + { + Cam_PositionDrag (); + Sys_UpdateWindows (W_XY|W_CAMERA|W_Z); + return; + } + + Sys_GetCursorPos (&cursorx, &cursory); + + if (buttons & (MK_LBUTTON | MK_MBUTTON) ) + { + Drag_MouseMoved (x, y, buttons); + Sys_UpdateWindows (W_XY|W_CAMERA|W_Z); + } +} + + +vec3_t cull1, cull2; +int cullv1[3], cullv2[3]; + +void InitCull (void) +{ + int i; + + VectorSubtract (camera.vpn, camera.vright, cull1); + VectorAdd (camera.vpn, camera.vright, cull2); + + for (i=0 ; i<3 ; i++) + { + if (cull1[i] > 0) + cullv1[i] = 3+i; + else + cullv1[i] = i; + if (cull2[i] > 0) + cullv2[i] = 3+i; + else + cullv2[i] = i; + } +} + +qboolean CullBrush (brush_t *b) +{ + int i; + vec3_t point; + float d; + + for (i=0 ; i<3 ; i++) + point[i] = b->mins[cullv1[i]] - camera.origin[i]; + + d = DotProduct (point, cull1); + if (d < -1) + return true; + + for (i=0 ; i<3 ; i++) + point[i] = b->mins[cullv2[i]] - camera.origin[i]; + + d = DotProduct (point, cull2); + if (d < -1) + return true; + + return false; +} + + +/* +============== +Cam_Draw +============== +*/ +void Cam_Draw (void) +{ + brush_t *brush; + face_t *face; + float screenaspect; + float yfov; + double start, end; + int i; + + if (!active_brushes.next) + return; // not valid yet + + if (camera.timing) + start = Sys_DoubleTime (); + + // + // clear + // + QE_CheckOpenGLForErrors(); + + glViewport(0, 0, camera.width, camera.height); + glScissor(0, 0, camera.width, camera.height); + glClearColor ( + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], + 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // + // set up viewpoint + // + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + + screenaspect = (float)camera.width/camera.height; + yfov = 2*atan((float)camera.height/camera.width)*180/Q_PI; + gluPerspective (yfov, screenaspect, 2, 8192); + + glRotatef (-90, 1, 0, 0); // put Z going up + glRotatef (90, 0, 0, 1); // put Z going up + glRotatef (camera.angles[0], 0, 1, 0); + glRotatef (-camera.angles[1], 0, 0, 1); + glTranslatef (-camera.origin[0], -camera.origin[1], -camera.origin[2]); + + Cam_BuildMatrix (); + + InitCull (); + + // + // draw stuff + // + + switch (camera.draw_mode) + { + case cd_wire: + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_1D); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glColor3f(1.0, 1.0, 1.0); +// glEnable (GL_LINE_SMOOTH); + break; + + case cd_solid: + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + glShadeModel (GL_FLAT); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_TEXTURE_2D); + + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glDepthFunc (GL_LEQUAL); + break; + + case cd_texture: + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + + glShadeModel (GL_FLAT); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_TEXTURE_2D); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glDepthFunc (GL_LEQUAL); + +#if 0 + + { + GLfloat fogColor[4] = {0.0, 1.0, 0.0, 0.25}; + + glFogi (GL_FOG_MODE, GL_LINEAR); + glHint (GL_FOG_HINT, GL_NICEST); /* per pixel */ + glFogf (GL_FOG_START, -8192); + glFogf (GL_FOG_END, 65536); + glFogfv (GL_FOG_COLOR, fogColor); + + } + +#endif + break; + + case cd_blend: + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + + glShadeModel (GL_FLAT); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_TEXTURE_2D); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glDisable(GL_DEPTH_TEST); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + } + + glMatrixMode(GL_TEXTURE); + for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) + { + if (CullBrush (brush)) + continue; + if (FilterBrush (brush)) + continue; + + Brush_Draw( brush ); + } + glMatrixMode(GL_PROJECTION); + + // + // now draw selected brushes + // + + glTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); + glMatrixMode(GL_TEXTURE); + + // draw normally + for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) + { + Brush_Draw( brush ); + } + + // blend on top + glMatrixMode(GL_PROJECTION); + + glColor4f(1.0, 0.0, 0.0, 0.3); + glEnable (GL_BLEND); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_TEXTURE_2D); + for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) + for (face=brush->brush_faces ; face ; face=face->next) + Face_Draw( face ); + if (selected_face) + Face_Draw(selected_face); + + // non-zbuffered outline + + glDisable (GL_BLEND); + glDisable (GL_DEPTH_TEST); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glColor3f (1, 1, 1); + for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) + for (face=brush->brush_faces ; face ; face=face->next) + Face_Draw( face ); + + // edge / vertex flags + + if (g_qeglobals.d_select_mode == sel_vertex) + { + glPointSize (4); + glColor3f (0,1,0); + glBegin (GL_POINTS); + for (i=0 ; i32); + + com_token[len] = 0; + return data; +} + + +int Q_strncasecmp (char *s1, char *s2, int n) +{ + int c1, c2; + + while (1) + { + c1 = *s1++; + c2 = *s2++; + + if (!n--) + return 0; // strings are equal until end point + + if (c1 != c2) + { + if (c1 >= 'a' && c1 <= 'z') + c1 -= ('a' - 'A'); + if (c2 >= 'a' && c2 <= 'z') + c2 -= ('a' - 'A'); + if (c1 != c2) + return -1; // strings not equal + } + if (!c1) + return 0; // strings are equal + } + + return -1; +} + +int Q_strcasecmp (char *s1, char *s2) +{ + return Q_strncasecmp (s1, s2, 99999); +} + + + +/* +============================================================================= + + MISC FUNCTIONS + +============================================================================= +*/ + + +int argc; +char *argv[MAX_NUM_ARGVS]; + +/* +============ +ParseCommandLine +============ +*/ +void ParseCommandLine (char *lpCmdLine) +{ + argc = 1; + argv[0] = "programname"; + + while (*lpCmdLine && (argc < MAX_NUM_ARGVS)) + { + while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) + lpCmdLine++; + + if (*lpCmdLine) + { + argv[argc] = lpCmdLine; + argc++; + + while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) + lpCmdLine++; + + if (*lpCmdLine) + { + *lpCmdLine = 0; + lpCmdLine++; + } + + } + } +} + + + +/* +================= +CheckParm + +Checks for the given parameter in the program's command line arguments +Returns the argument number (1 to argc-1) or 0 if not present +================= +*/ +int CheckParm (char *check) +{ + int i; + + for (i = 1;i 0 && path[length] != PATHSEPERATOR) + length--; + path[length] = 0; +} + +void StripExtension (char *path) +{ + int length; + + length = strlen(path)-1; + while (length > 0 && path[length] != '.') + { + length--; + if (path[length] == '/') + return; // no extension + } + if (length) + path[length] = 0; +} + + +/* +==================== +Extract file parts +==================== +*/ +void ExtractFilePath (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// + while (src != path && *(src-1) != PATHSEPERATOR) + src--; + + memcpy (dest, path, src-path); + dest[src-path] = 0; +} + +void ExtractFileName (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// + while (src != path && *(src-1) != '/' + && *(src-1) != '\\' ) + src--; + + while (*src) + { + *dest++ = *src++; + } + *dest = 0; +} + +void ExtractFileBase (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a \ or the start +// + while (src != path && *(src-1) != '/' + && *(src-1) != '\\' ) + src--; + + while (*src && *src != '.') + { + *dest++ = *src++; + } + *dest = 0; +} + +void ExtractFileExtension (char *path, char *dest) +{ + char *src; + + src = path + strlen(path) - 1; + +// +// back up until a . or the start +// + while (src != path && *(src-1) != '.') + src--; + if (src == path) + { + *dest = 0; // no extension + return; + } + + strcpy (dest,src); +} + + +/* +============== +ParseNum / ParseHex +============== +*/ +int ParseHex (char *hex) +{ + char *str; + int num; + + num = 0; + str = hex; + + while (*str) + { + num <<= 4; + if (*str >= '0' && *str <= '9') + num += *str-'0'; + else if (*str >= 'a' && *str <= 'f') + num += 10 + *str-'a'; + else if (*str >= 'A' && *str <= 'F') + num += 10 + *str-'A'; + else + Error ("Bad hex number: %s",hex); + str++; + } + + return num; +} + + +int ParseNum (char *str) +{ + if (str[0] == '$') + return ParseHex (str+1); + if (str[0] == '0' && str[1] == 'x') + return ParseHex (str+2); + return atol (str); +} + + + +/* +============================================================================ + + BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +#ifdef _SGI_SOURCE +#define __BIG_ENDIAN__ +#endif + +#ifdef __BIG_ENDIAN__ + +short LittleShort (short l) +{ + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short BigShort (short l) +{ + return l; +} + + +int LittleLong (int l) +{ + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int BigLong (int l) +{ + return l; +} + + +float LittleFloat (float l) +{ + union {byte b[4]; float f;} in, out; + + in.f = l; + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + return out.f; +} + +float BigFloat (float l) +{ + return l; +} + + +#else + + +short BigShort (short l) +{ + byte b1,b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short LittleShort (short l) +{ + return l; +} + + +int BigLong (int l) +{ + byte b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int LittleLong (int l) +{ + return l; +} + +float BigFloat (float l) +{ + union {byte b[4]; float f;} in, out; + + in.f = l; + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + return out.f; +} + +float LittleFloat (float l) +{ + return l; +} + + + +#endif + diff --git a/tools/quake2/extra/qe4/cmdlib.h b/tools/quake2/extra/qe4/cmdlib.h new file mode 100644 index 00000000..b748950c --- /dev/null +++ b/tools/quake2/extra/qe4/cmdlib.h @@ -0,0 +1,99 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// cmdlib.h + +#ifndef __CMDLIB__ +#define __CMDLIB__ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef __BYTEBOOL__ +#define __BYTEBOOL__ +typedef enum {false, true} qboolean; +typedef unsigned char byte; +#endif + +// the dec offsetof macro doesn't work very well... +#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier) + + +// set these before calling CheckParm +extern int myargc; +extern char **myargv; + +int Q_strncasecmp (char *s1, char *s2, int n); +int Q_strcasecmp (char *s1, char *s2); + +int Q_filelength (FILE *f); + +double I_FloatTime (void); + +void Error (char *error, ...); +int CheckParm (char *check); +void ParseCommandLine (char *lpCmdLine); + +FILE *SafeOpenWrite (char *filename); +FILE *SafeOpenRead (char *filename); +void SafeRead (FILE *f, void *buffer, int count); +void SafeWrite (FILE *f, void *buffer, int count); + +int LoadFile (char *filename, void **bufferptr); +int LoadFileNoCrash (char *filename, void **bufferptr); +void SaveFile (char *filename, void *buffer, int count); + +void DefaultExtension (char *path, char *extension); +void DefaultPath (char *path, char *basepath); +void StripFilename (char *path); +void StripExtension (char *path); + +void ExtractFilePath (char *path, char *dest); +void ExtractFileName (char *path, char *dest); +void ExtractFileBase (char *path, char *dest); +void ExtractFileExtension (char *path, char *dest); + +int ParseNum (char *str); + +short BigShort (short l); +short LittleShort (short l); +int BigLong (int l); +int LittleLong (int l); +float BigFloat (float l); +float LittleFloat (float l); + + +char *COM_Parse (char *data); + +extern char com_token[1024]; +extern qboolean com_eof; + +#define MAX_NUM_ARGVS 32 +extern int argc; +extern char *argv[MAX_NUM_ARGVS]; + +#endif diff --git a/tools/quake2/extra/qe4/csg.c b/tools/quake2/extra/qe4/csg.c new file mode 100644 index 00000000..e36a2ade --- /dev/null +++ b/tools/quake2/extra/qe4/csg.c @@ -0,0 +1,168 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +/* +============== +CSG_SplitBrushByFace + +The incoming brush is NOT freed. +The incoming face is NOT left referenced. +============== +*/ +void CSG_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back) +{ + brush_t *b; + face_t *nf; + vec3_t temp; + + b = Brush_Clone (in); + nf = Face_Clone (f); + + nf->texdef = b->brush_faces->texdef; + nf->next = b->brush_faces; + b->brush_faces = nf; + + Brush_Build( b ); + Brush_RemoveEmptyFaces ( b ); + if ( !b->brush_faces ) + { // completely clipped away + Brush_Free (b); + *back = NULL; + } + else + { + Entity_LinkBrush (in->owner, b); + *back = b; + } + + b = Brush_Clone (in); + nf = Face_Clone (f); + // swap the plane winding + VectorCopy (nf->planepts[0], temp); + VectorCopy (nf->planepts[1], nf->planepts[0]); + VectorCopy (temp, nf->planepts[1]); + + nf->texdef = b->brush_faces->texdef; + nf->next = b->brush_faces; + b->brush_faces = nf; + + Brush_Build( b ); + Brush_RemoveEmptyFaces ( b ); + if ( !b->brush_faces ) + { // completely clipped away + Brush_Free (b); + *front = NULL; + } + else + { + Entity_LinkBrush (in->owner, b); + *front = b; + } +} + +/* +============= +CSG_MakeHollow +============= +*/ +void CSG_MakeHollow (void) +{ + brush_t *b, *front, *back, *next; + face_t *f; + face_t split; + vec3_t move; + int i; + + for (b = selected_brushes.next ; b != &selected_brushes ; b=next) + { + next = b->next; + for (f = b->brush_faces ; f ; f=f->next) + { + split = *f; + VectorScale (f->plane.normal, g_qeglobals.d_gridsize, move); + for (i=0 ; i<3 ; i++) + VectorSubtract (split.planepts[i], move, split.planepts[i]); + + CSG_SplitBrushByFace (b, &split, &front, &back); + if (back) + Brush_Free (back); + if (front) + Brush_AddToList (front, &selected_brushes); + } + Brush_Free (b); + } + Sys_UpdateWindows (W_ALL); +} + + +/* +============= +CSG_Subtract +============= +*/ +void CSG_Subtract (void) +{ + brush_t *b, *s, *frag, *front, *back, *next, *snext; + face_t *f; + int i; + + Sys_Printf ("Subtracting...\n"); + + for (b = selected_brushes.next ; b != &selected_brushes ; b=next) + { + next = b->next; + + if (b->owner->eclass->fixedsize) + continue; // can't use texture from a fixed entity, so don't subtract + + for (s=active_brushes.next ; s != &active_brushes ; s=snext) + { + snext = s->next; + if (s->owner->eclass->fixedsize) + continue; + + for (i=0 ; i<3 ; i++) + if (b->mins[i] >= s->maxs[i] - ON_EPSILON + || b->maxs[i] <= s->mins[i] + ON_EPSILON) + break; + if (i != 3) + continue; // definately don't touch + + frag = s; + for (f = b->brush_faces ; f && frag ; f=f->next) + { + CSG_SplitBrushByFace (frag, f, &front, &back); + Brush_Free (frag); + frag = back; + if (front) + Brush_AddToList (front, &active_brushes); + } + if (frag) + Brush_Free (frag); + } + } + + Sys_Printf ("done.\n"); + Sys_UpdateWindows (W_ALL); +} diff --git a/tools/quake2/extra/qe4/drag.c b/tools/quake2/extra/qe4/drag.c new file mode 100644 index 00000000..2418325e --- /dev/null +++ b/tools/quake2/extra/qe4/drag.c @@ -0,0 +1,457 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +/* + + drag either multiple brushes, or select plane points from + a single brush. + +*/ + +qboolean drag_ok; +vec3_t drag_xvec; +vec3_t drag_yvec; + +static int buttonstate; +static int pressx, pressy; +static vec3_t pressdelta; +static int buttonx, buttony; + + +//int num_move_points; +//float *move_points[1024]; + +int lastx, lasty; + +qboolean drag_first; + + +void AxializeVector (vec3_t v) +{ + vec3_t a; + float o; + int i; + + if (!v[0] && !v[1]) + return; + if (!v[1] && !v[2]) + return; + if (!v[0] && !v[2]) + return; + + for (i=0 ; i<3 ; i++) + a[i] = fabs(v[i]); + if (a[0] > a[1] && a[0] > a[2]) + i = 0; + else if (a[1] > a[0] && a[1] > a[2]) + i = 1; + else + i = 2; + + o = v[i]; + VectorCopy (vec3_origin, v); + if (o<0) + v[i] = -1; + else + v[i] = 1; + +} + + +/* +=========== +Drag_Setup +=========== +*/ +void Drag_Setup (int x, int y, int buttons, + vec3_t xaxis, vec3_t yaxis, + vec3_t origin, vec3_t dir) +{ + trace_t t; + face_t *f; + + if (selected_brushes.next == &selected_brushes) + { + Sys_Status("No selection to drag\n", 0); + return; + } + + drag_first = true; + g_qeglobals.d_num_move_points = 0; + VectorCopy (vec3_origin, pressdelta); + pressx = x; + pressy = y; + + VectorCopy (xaxis, drag_xvec); + AxializeVector (drag_xvec); + VectorCopy (yaxis, drag_yvec); + AxializeVector (drag_yvec); + + if (g_qeglobals.d_select_mode == sel_vertex) + { + SelectVertexByRay (origin, dir); + if (g_qeglobals.d_num_move_points) + { + drag_ok = true; + return; + } + } + if (g_qeglobals.d_select_mode == sel_edge) + { + SelectEdgeByRay (origin, dir); + if (g_qeglobals.d_num_move_points) + { + drag_ok = true; + return; + } + } + + + // + // check for direct hit first + // + t = Test_Ray (origin, dir, true); + if (t.selected) + { + drag_ok = true; + + if (buttons == (MK_LBUTTON|MK_CONTROL) ) + { + Sys_Printf ("Shear dragging face\n"); + Brush_SelectFaceForDragging (t.brush, t.face, true); + } + else if (buttons == (MK_LBUTTON|MK_CONTROL|MK_SHIFT) ) + { + Sys_Printf ("Sticky dragging brush\n"); + for (f=t.brush->brush_faces ; f ; f=f->next) + Brush_SelectFaceForDragging (t.brush, f, false); + } + else + Sys_Printf ("Dragging entire selection\n"); + + return; + } + + if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge) + return; + + // + // check for side hit + // + if (selected_brushes.next->next != &selected_brushes) + { + Sys_Printf ("Click isn't inside multiple selection\n"); + return; + } + + if (selected_brushes.next->owner->eclass->fixedsize) + { + Sys_Printf ("Can't stretch fixed size entities\n"); + return; + } + + + if (buttons & MK_CONTROL) + Brush_SideSelect (selected_brushes.next, origin, dir, true); + else + Brush_SideSelect (selected_brushes.next, origin, dir, false); + + + Sys_Printf ("Side stretch\n"); + drag_ok = true; +} + +entity_t *peLink; + +void UpdateTarget(vec3_t origin, vec3_t dir) +{ + trace_t t; + entity_t *pe; + int i; + char sz[128]; + + t = Test_Ray (origin, dir, 0); + + if (!t.brush) + return; + + pe = t.brush->owner; + + if (pe == NULL) + return; + + // is this the first? + if (peLink != NULL) + { + + // Get the target id from out current target + // if there is no id, make one + + i = IntForKey(pe, "target"); + if (i <= 0) + { + i = GetUniqueTargetId(1); + sprintf(sz, "%d", i); + + SetKeyValue(pe, "target", sz); + } + + // set the target # into our src + + sprintf(sz, "%d", i); + SetKeyValue(peLink, "targetname", sz); + + Sys_UpdateWindows(W_ENTITY); + + } + + // promote the target to the src + + peLink = pe; + +} + +/* +=========== +Drag_Begin +=========== +*/ +void Drag_Begin (int x, int y, int buttons, + vec3_t xaxis, vec3_t yaxis, + vec3_t origin, vec3_t dir) +{ + trace_t t; + + drag_ok = false; + VectorCopy (vec3_origin, pressdelta); + + drag_first = true; + peLink = NULL; + + // shift LBUTTON = select entire brush + if (buttons == (MK_LBUTTON | MK_SHIFT)) + { + if (!dir[0] && !dir[1]) + Select_Ray (origin, dir, SF_ENTITIES_FIRST); // hack for XY + else + Select_Ray (origin, dir, 0); + return; + } + + // ctrl-shift LBUTTON = select single face + if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) + { + Select_Deselect (); + Select_Ray (origin, dir, SF_SINGLEFACE); + return; + } + + // LBUTTON + all other modifiers = manipulate selection + if (buttons & MK_LBUTTON) + { + Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir); + return; + } + + // middle button = grab texture + if (buttons == MK_MBUTTON) + { + t = Test_Ray (origin, dir, false); + if (t.face) + { + g_qeglobals.d_new_brush_bottom_z = t.brush->mins[2]; + g_qeglobals.d_new_brush_top_z = t.brush->maxs[2]; + Texture_SetTexture (&t.face->texdef); + } + else + Sys_Printf ("Did not select a texture\n"); + return; + } + + // ctrl-middle button = set entire brush to texture + if (buttons == (MK_MBUTTON|MK_CONTROL) ) + { + t = Test_Ray (origin, dir, false); + if (t.brush) + { + if (t.brush->brush_faces->texdef.name[0] == '(') + Sys_Printf ("Can't change an entity texture\n"); + else + { + Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef); + Sys_UpdateWindows (W_ALL); + } + } + else + Sys_Printf ("Didn't hit a btrush\n"); + return; + } + + // ctrl-shift-middle button = set single face to texture + if (buttons == (MK_MBUTTON|MK_SHIFT|MK_CONTROL) ) + { + t = Test_Ray (origin, dir, false); + if (t.brush) + { + if (t.brush->brush_faces->texdef.name[0] == '(') + Sys_Printf ("Can't change an entity texture\n"); + else + { + t.face->texdef = g_qeglobals.d_texturewin.texdef; + Brush_Build( t.brush ); + Sys_UpdateWindows (W_ALL); + } + } + else + Sys_Printf ("Didn't hit a btrush\n"); + return; + } + +} + + +/* +=========== +MoveSelection +=========== +*/ +void MoveSelection (vec3_t move) +{ + int i; + brush_t *b; + + if (!move[0] && !move[1] && !move[2]) + return; + + Sys_UpdateWindows (W_XY|W_CAMERA); + + // + // dragging only a part of the selection + // + if (g_qeglobals.d_num_move_points) + { + for (i=0 ; inext) + { + Brush_Build( b ); + for (i=0 ; i<3 ; i++) + if (b->mins[i] > b->maxs[i] + || b->maxs[i] - b->mins[i] > 4096) + break; // dragged backwards or fucked up + if (i != 3) + break; + } + + // if any of the brushes were crushed out of existance + // calcel the entire move + if (b != &selected_brushes) + { + Sys_Printf ("Brush dragged backwards, move canceled\n"); + for (i=0 ; inext) + Brush_Build( b ); + } + + } + else + { + // + // if there are lots of brushes selected, just translate instead + // of rebuilding the brushes + // + if (drag_yvec[2] == 0 && selected_brushes.next->next != &selected_brushes) + { + VectorAdd (g_qeglobals.d_select_translate, move, g_qeglobals.d_select_translate); + } + else + { + Select_Move (move); + } + } +} + +/* +=========== +Drag_MouseMoved +=========== +*/ +void Drag_MouseMoved (int x, int y, int buttons) +{ + vec3_t move, delta; + int i; + char movestring[128]; + + if (!buttons) + { + drag_ok = false; + return; + } + if (!drag_ok) + return; + + // clear along one axis + if (buttons & MK_SHIFT) + { + drag_first = false; + if (abs(x-pressx) > abs(y-pressy)) + y = pressy; + else + x = pressx; + } + + + for (i=0 ; i<3 ; i++) + { + move[i] = drag_xvec[i]*(x - pressx) + + drag_yvec[i]*(y - pressy); + move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + } + + sprintf (movestring, "drag (%i %i %i)", (int)move[0], (int)move[1], (int)move[2]); + Sys_Status (movestring, 0); + + VectorSubtract (move, pressdelta, delta); + MoveSelection (delta); + VectorCopy (move, pressdelta); +} + +/* +=========== +Drag_MouseUp +=========== +*/ +void Drag_MouseUp (void) +{ + Sys_Status ("drag completed.", 0); + if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2]) + { + Select_Move (g_qeglobals.d_select_translate); + VectorCopy (vec3_origin, g_qeglobals.d_select_translate); + Sys_UpdateWindows (W_CAMERA); + } +} diff --git a/tools/quake2/extra/qe4/eclass.c b/tools/quake2/extra/qe4/eclass.c new file mode 100644 index 00000000..466d8a48 --- /dev/null +++ b/tools/quake2/extra/qe4/eclass.c @@ -0,0 +1,281 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" +#include "io.h" + +eclass_t *eclass; +eclass_t *eclass_bad; +char eclass_directory[1024]; + +/* + +the classname, color triple, and bounding box are parsed out of comments +A ? size means take the exact brush size. + +/*QUAKED (0 0 0) ? +/*QUAKED (0 0 0) (-8 -8 -8) (8 8 8) + +Flag names can follow the size description: + +/*QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY + +*/ +char *debugname; + +eclass_t *Eclass_InitFromText (char *text) +{ + char *t; + int len; + int r, i; + char parms[256], *p; + eclass_t *e; + char color[128]; + + e = qmalloc(sizeof(*e)); + memset (e, 0, sizeof(*e)); + + text += strlen("/*QUAKED "); + +// grab the name + text = COM_Parse (text); + e->name = qmalloc (strlen(com_token)+1); + strcpy (e->name, com_token); + debugname = e->name; + +// grab the color, reformat as texture name + r = sscanf (text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]); + if (r != 3) + return e; + sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]); + strcpy (e->texdef.name, color); + + while (*text != ')') + { + if (!*text) + return e; + text++; + } + text++; + +// get the size + text = COM_Parse (text); + if (com_token[0] == '(') + { // parse the size as two vectors + e->fixedsize = true; + r = sscanf (text,"%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2], + &e->maxs[0], &e->maxs[1], &e->maxs[2]); + if (r != 6) + return e; + + for (i=0 ; i<2 ; i++) + { + while (*text != ')') + { + if (!*text) + return e; + text++; + } + text++; + } + } + else + { // use the brushes + } + +// get the flags + + +// copy to the first /n + p = parms; + while (*text && *text != '\n') + *p++ = *text++; + *p = 0; + text++; + +// any remaining words are parm flags + p = parms; + for (i=0 ; i<8 ; i++) + { + p = COM_Parse (p); + if (!p) + break; + strcpy (e->flagnames[i], com_token); + } + +// find the length until close comment + for (t=text ; t[0] && !(t[0]=='*' && t[1]=='/') ; t++) + ; + +// copy the comment block out + len = t-text; + e->comments = qmalloc (len+1); + memcpy (e->comments, text, len); +#if 0 + for (i=0 ; icomments[i] = '\r'; + else + e->comments[i] = text[i]; +#endif + e->comments[len] = 0; + + return e; +} + + +/* +================= +Eclass_InsertAlphabetized +================= +*/ +void Eclass_InsertAlphabetized (eclass_t *e) +{ + eclass_t *s; + + if (!eclass) + { + eclass = e; + return; + } + + + s = eclass; + if (stricmp (e->name, s->name) < 0) + { + e->next = s; + eclass = e; + return; + } + + do + { + if (!s->next || stricmp (e->name, s->next->name) < 0) + { + e->next = s->next; + s->next = e; + return; + } + s=s->next; + } while (1); +} + + +/* +================= +Eclass_ScanFile +================= +*/ +void Eclass_ScanFile (char *filename) +{ + int size; + char *data; + eclass_t *e; + int i; + char temp[1024]; + + QE_ConvertDOSToUnixName( temp, filename ); + + Sys_Printf ("ScanFile: %s\n", temp); + + size = LoadFile (filename, (void *)&data); + + for (i=0 ; inext) + if (!strcmp (name, e->name)) + return e; + + // create a new class for it + if (has_brushes) + { + sprintf (init, "/*QUAKED %s (0 0.5 0) ?\nNot found in source.\n", name); + e = Eclass_InitFromText (init); + } + else + { + sprintf (init, "/*QUAKED %s (0 0.5 0) (-8 -8 -8) (8 8 8)\nNot found in source.\n", name); + e = Eclass_InitFromText (init); + } + + Eclass_InsertAlphabetized (e); + + return e; +} + diff --git a/tools/quake2/extra/qe4/entity.c b/tools/quake2/extra/qe4/entity.c new file mode 100644 index 00000000..7cbe14ae --- /dev/null +++ b/tools/quake2/extra/qe4/entity.c @@ -0,0 +1,538 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +char *ValueForKey (entity_t *ent, char *key) +{ + epair_t *ep; + + for (ep=ent->epairs ; ep ; ep=ep->next) + if (!strcmp (ep->key, key) ) + return ep->value; + return ""; +} + +void SetKeyValue (entity_t *ent, char *key, char *value) +{ + epair_t *ep; + + if (ent == NULL) + return; + + if (!key || !key[0]) + return; + + for (ep=ent->epairs ; ep ; ep=ep->next) + if (!strcmp (ep->key, key) ) + { + free (ep->value); + ep->value = qmalloc(strlen(value)+1); + strcpy (ep->value, value); + return; + } + ep = qmalloc (sizeof(*ep)); + ep->next = ent->epairs; + ent->epairs = ep; + ep->key = qmalloc(strlen(key)+1); + strcpy (ep->key, key); + ep->value = qmalloc(strlen(value)+1); + strcpy (ep->value, value); +} + +void DeleteKey (entity_t *ent, char *key) +{ + epair_t **ep, *next; + + ep = &ent->epairs; + while (*ep) + { + next = *ep; + if ( !strcmp (next->key, key) ) + { + *ep = next->next; + free(next->key); + free(next->value); + free(next); + return; + } + ep = &next->next; + } +} + +float FloatForKey (entity_t *ent, char *key) +{ + char *k; + + k = ValueForKey (ent, key); + return atof(k); +} + +int IntForKey (entity_t *ent, char *key) +{ + char *k; + + k = ValueForKey (ent, key); + return atoi(k); +} + +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec) +{ + char *k; + + k = ValueForKey (ent, key); + sscanf (k, "%f %f %f", &vec[0], &vec[1], &vec[2]); +} + + +/* +=============== +Entity_Free + +Frees the entity and any brushes is has. +The entity is removed from the global entities list. +=============== +*/ +void Entity_Free (entity_t *e) +{ + epair_t *ep, *next; + + while (e->brushes.onext != &e->brushes) + Brush_Free (e->brushes.onext); + + if (e->next) + { + e->next->prev = e->prev; + e->prev->next = e->next; + } + + for (ep = e->epairs ; ep ; ep=next) + { + next = ep->next; + free (ep); + } + free (e); +} + +/* +================= +ParseEpair +================= +*/ +epair_t *ParseEpair (void) +{ + epair_t *e; + + e = qmalloc (sizeof(*e)); + + e->key = qmalloc(strlen(token)+1); + strcpy (e->key, token); + + GetToken (false); + e->value = qmalloc(strlen(token)+1); + strcpy (e->value, token); + + return e; +} + +/* +================ +Entity_Parse + +If onlypairs is set, the classname info will not +be looked up, and the entity will not be added +to the global list. Used for parsing the project. +================ +*/ +entity_t *Entity_Parse (qboolean onlypairs) +{ + entity_t *ent; + eclass_t *e; + brush_t *b; + vec3_t mins, maxs; + epair_t *ep; + qboolean has_brushes; + + if (!GetToken (true)) + return NULL; + + if (strcmp (token, "{") ) + Error ("ParseEntity: { not found"); + + ent = qmalloc (sizeof(*ent)); + ent->brushes.onext = ent->brushes.oprev = &ent->brushes; + + do + { + if (!GetToken (true)) + Error ("ParseEntity: EOF without closing brace"); + if (!strcmp (token, "}") ) + break; + if (!strcmp (token, "{") ) + { + b = Brush_Parse (); + b->owner = ent; + + // add to the end of the entity chain + b->onext = &ent->brushes; + b->oprev = ent->brushes.oprev; + ent->brushes.oprev->onext = b; + ent->brushes.oprev = b; + } + else + { + ep = ParseEpair (); + ep->next = ent->epairs; + ent->epairs = ep; + } + } while (1); + + if (onlypairs) + return ent; + + if (ent->brushes.onext == &ent->brushes) + has_brushes = false; + else + has_brushes = true; + + GetVectorForKey (ent, "origin", ent->origin); + + e = Eclass_ForName (ValueForKey (ent, "classname"), has_brushes); + ent->eclass = e; + if (e->fixedsize) + { // fixed size entity + if (ent->brushes.onext != &ent->brushes) + { + printf ("Warning: Fixed size entity with brushes\n"); +#if 0 + while (ent->brushes.onext != &ent->brushes) + { // FIXME: this will free the entity and crash! + Brush_Free (b); + } +#endif +ent->brushes.next = ent->brushes.prev = &ent->brushes; + } + // create a custom brush + VectorAdd (e->mins, ent->origin, mins); + VectorAdd (e->maxs, ent->origin, maxs); + b = Brush_Create (mins, maxs, &e->texdef); + b->owner = ent; + + b->onext = ent->brushes.onext; + b->oprev = &ent->brushes; + ent->brushes.onext->oprev = b; + ent->brushes.onext = b; + } + else + { // brush entity + if (ent->brushes.next == &ent->brushes) + printf ("Warning: Brush entity with no brushes\n"); + } + + // add all the brushes to the main list + for (b=ent->brushes.onext ; b != &ent->brushes ; b=b->onext) + { + b->next = active_brushes.next; + active_brushes.next->prev = b; + b->prev = &active_brushes; + active_brushes.next = b; + } + + return ent; +} + +/* +============ +Entity_Write +============ +*/ +void Entity_Write (entity_t *e, FILE *f, qboolean use_region) +{ + epair_t *ep; + brush_t *b; + vec3_t origin; + char text[128]; + int count; + + // if none of the entities brushes are in the region, + // don't write the entity at all + if (use_region) + { + // in region mode, save the camera position as playerstart + if ( !strcmp(ValueForKey (e, "classname"), "info_player_start") ) + { + fprintf (f, "{\n"); + fprintf (f, "\"classname\" \"info_player_start\"\n"); + fprintf (f, "\"origin\" \"%i %i %i\"\n", (int)camera.origin[0], + (int)camera.origin[1], (int)camera.origin[2]); + fprintf (f, "\"angle\" \"%i\"\n", (int)camera.angles[YAW]); + fprintf (f, "}\n"); + return; + } + + for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext) + if (!Map_IsBrushFiltered(b)) + break; // got one + + if (b == &e->brushes) + return; // nothing visible + } + + // if fixedsize, calculate a new origin based on the current + // brush position + if (e->eclass->fixedsize) + { + VectorSubtract (e->brushes.onext->mins, e->eclass->mins, origin); + sprintf (text, "%i %i %i", (int)origin[0], + (int)origin[1], (int)origin[2]); + SetKeyValue (e, "origin", text); + } + + fprintf (f, "{\n"); + for (ep = e->epairs ; ep ; ep=ep->next) + fprintf (f, "\"%s\" \"%s\"\n", ep->key, ep->value); + + if (!e->eclass->fixedsize) + { + count = 0; + for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext) + { + if (!use_region || !Map_IsBrushFiltered (b)) + { + fprintf (f, "// brush %i\n", count); + count++; + Brush_Write (b, f); + } + } + } + fprintf (f, "}\n"); +} + + + +/* +============ +Entity_Create + +Creates a new entity out of the selected_brushes list. +If the entity class is fixed size, the brushes are only +used to find a midpoint. Otherwise, the brushes have +their ownershi[ transfered to the new entity. +============ +*/ +entity_t *Entity_Create (eclass_t *c) +{ + entity_t *e; + brush_t *b; + vec3_t mins, maxs; + int i; + + // check to make sure the brushes are ok + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + if (b->owner != world_entity) + { + Sys_Printf ("Entity NOT created, brushes not all from world\n"); + Sys_Beep (); + return NULL; + } + + // create it + + e = qmalloc(sizeof(*e)); + e->brushes.onext = e->brushes.oprev = &e->brushes; + e->eclass = c; + SetKeyValue (e, "classname", c->name); + + // add the entity to the entity list + e->next = entities.next; + entities.next = e; + e->next->prev = e; + e->prev = &entities; + + if (c->fixedsize) + { + // + // just use the selection for positioning + // + b = selected_brushes.next; + for (i=0 ; i<3 ; i++) + e->origin[i] = b->mins[i] - c->mins[i]; + + // create a custom brush + VectorAdd (c->mins, e->origin, mins); + VectorAdd (c->maxs, e->origin, maxs); + b = Brush_Create (mins, maxs, &c->texdef); + + Entity_LinkBrush (e, b); + + // delete the current selection + Select_Delete (); + + // select the new brush + b->next = b->prev = &selected_brushes; + selected_brushes.next = selected_brushes.prev = b; + + Brush_Build( b ); + } + else + { + // + // change the selected brushes over to the new entity + // + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + { + Entity_UnlinkBrush (b); + Entity_LinkBrush (e, b); + Brush_Build( b ); // so the key brush gets a name + } + } + + Sys_UpdateWindows (W_ALL); + return e; +} + + +/* +=========== +Entity_LinkBrush +=========== +*/ +void Entity_LinkBrush (entity_t *e, brush_t *b) +{ + if (b->oprev || b->onext) + Error ("Entity_LinkBrush: Allready linked"); + b->owner = e; + + b->onext = e->brushes.onext; + b->oprev = &e->brushes; + e->brushes.onext->oprev = b; + e->brushes.onext = b; +} + +/* +=========== +Entity_UnlinkBrush +=========== +*/ +void Entity_UnlinkBrush (brush_t *b) +{ + if (!b->owner || !b->onext || !b->oprev) + Error ("Entity_UnlinkBrush: Not currently linked"); + b->onext->oprev = b->oprev; + b->oprev->onext = b->onext; + b->onext = b->oprev = NULL; + b->owner = NULL; +} + + + +/* +=========== +Entity_Clone +=========== +*/ +entity_t *Entity_Clone (entity_t *e) +{ + entity_t *n; + epair_t *ep, *np; + + n = qmalloc(sizeof(*n)); + n->brushes.onext = n->brushes.oprev = &n->brushes; + n->eclass = e->eclass; + + // add the entity to the entity list + n->next = entities.next; + entities.next = n; + n->next->prev = n; + n->prev = &entities; + + for (ep = e->epairs ; ep ; ep=ep->next) + { + np = qmalloc(sizeof(*np)); + np->key = copystring(ep->key); + np->value = copystring(ep->value); + np->next = n->epairs; + n->epairs = np; + } + return n; +} + +int GetUniqueTargetId(int iHint) +{ + int iMin, iMax, i; + BOOL fFound; + entity_t *pe; + + fFound = FALSE; + pe = entities.next; + iMin = 0; + iMax = 0; + + for (; pe != NULL && pe != &entities ; pe = pe->next) + { + i = IntForKey(pe, "target"); + if (i) + { + iMin = min(i, iMin); + iMax = max(i, iMax); + if (i == iHint) + fFound = TRUE; + } + } + + if (fFound) + return iMax + 1; + else + return iHint; +} + +entity_t *FindEntity(char *pszKey, char *pszValue) +{ + entity_t *pe; + + pe = entities.next; + + for (; pe != NULL && pe != &entities ; pe = pe->next) + { + if (!strcmp(ValueForKey(pe, pszKey), pszValue)) + return pe; + } + + return NULL; +} + +entity_t *FindEntityInt(char *pszKey, int iValue) +{ + entity_t *pe; + + pe = entities.next; + + for (; pe != NULL && pe != &entities ; pe = pe->next) + { + if (IntForKey(pe, pszKey) == iValue) + return pe; + } + + return NULL; +} + diff --git a/tools/quake2/extra/qe4/entity.h b/tools/quake2/extra/qe4/entity.h new file mode 100644 index 00000000..012f08dc --- /dev/null +++ b/tools/quake2/extra/qe4/entity.h @@ -0,0 +1,84 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// entity.h + + +#define MAX_FLAGS 8 + +typedef struct eclass_s +{ + struct eclass_s *next; + char *name; + qboolean fixedsize; + qboolean unknown; // wasn't found in source + vec3_t mins, maxs; + vec3_t color; + texdef_t texdef; + char *comments; + char flagnames[MAX_FLAGS][32]; +} eclass_t; + +extern eclass_t *eclass; + +void Eclass_InitForSourceDirectory (char *path); +eclass_t *Eclass_ForName (char *name, qboolean has_brushes); + +//=================================================== + + +typedef struct epair_s +{ + struct epair_s *next; + char *key; + char *value; +} epair_t; + +typedef struct entity_s +{ + struct entity_s *prev, *next; + brush_t brushes; // head/tail of list + vec3_t origin; + eclass_t *eclass; + epair_t *epairs; +} entity_t; + +char *ValueForKey (entity_t *ent, char *key); +void SetKeyValue (entity_t *ent, char *key, char *value); +void DeleteKey (entity_t *ent, char *key); +float FloatForKey (entity_t *ent, char *key); +int IntForKey (entity_t *ent, char *key); +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec); + +void Entity_Free (entity_t *e); +entity_t *Entity_Parse (qboolean onlypairs); +void Entity_Write (entity_t *e, FILE *f, qboolean use_region); +entity_t *Entity_Create (eclass_t *c); +entity_t *Entity_Clone (entity_t *e); + +void Entity_LinkBrush (entity_t *e, brush_t *b); +void Entity_UnlinkBrush (brush_t *b); +entity_t *FindEntity(char *pszKey, char *pszValue); +entity_t *FindEntityInt(char *pszKey, int iValue); + +int GetUniqueTargetId(int iHint); + diff --git a/tools/quake2/extra/qe4/entityw.h b/tools/quake2/extra/qe4/entityw.h new file mode 100644 index 00000000..d3f7bd05 --- /dev/null +++ b/tools/quake2/extra/qe4/entityw.h @@ -0,0 +1,66 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// entity.h + +#define DlgXBorder 5 +#define DlgYBorder 5 + + +#define EntList 0 +#define EntComment 1 +#define EntCheck1 2 +#define EntCheck2 3 +#define EntCheck3 4 +#define EntCheck4 5 +#define EntCheck5 6 +#define EntCheck6 7 +#define EntCheck7 8 +#define EntCheck8 9 +#define EntCheck9 10 +#define EntCheck10 11 +#define EntCheck11 12 +#define EntCheck12 13 +#define EntProps 14 +#define EntDir0 15 +#define EntDir45 16 +#define EntDir90 17 +#define EntDir135 18 +#define EntDir180 19 +#define EntDir225 20 +#define EntDir270 21 +#define EntDir315 22 +#define EntDirUp 23 +#define EntDirDown 24 +#define EntDelProp 25 +#define EntKeyLabel 26 +#define EntKeyField 27 +#define EntValueLabel 28 +#define EntValueField 29 +#define EntColor 30 + +#define EntLast 31 + +extern HWND hwndEnt[EntLast]; + +extern int rgIds[EntLast]; + diff --git a/tools/quake2/extra/qe4/glingr.h b/tools/quake2/extra/qe4/glingr.h new file mode 100644 index 00000000..19cb1c5e --- /dev/null +++ b/tools/quake2/extra/qe4/glingr.h @@ -0,0 +1,98 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// This .h file contains constants, typedefs, etc. for Intergraph +// extensions to OpenGL. These extensions are: +// +// Multiple Palette Extension +// Texture Object Extension + +#define GL_INGR_multiple_palette 1 +#define GL_EXT_texture_object 1 + + +// New constants and typedefs for the Multiple Palette Extension +#define GL_PALETTE_INGR 0x80c0 +#define GL_MAX_PALETTES_INGR 0x80c1 +#define GL_MAX_PALETTE_ENTRIES_INGR 0x80c2 +#define GL_CURRENT_PALETTE_INGR 0x80c3 +#define GL_PALETTE_WRITEMASK_INGR 0x80c4 +#define GL_CURRENT_RASTER_PALETTE_INGR 0x80c5 +#define GL_PALETTE_CLEAR_VALUE_INGR 0x80c6 + +// Function prototypes for the Multiple Palette Extension routines +typedef void (APIENTRY *PALETTEFUNCPTR)(GLuint); +typedef void (APIENTRY *PALETTEMASKFUNCPTR)(GLboolean); +typedef void (APIENTRY *WGLLOADPALETTEFUNCPTR)(GLuint, GLsizei, GLuint *); +typedef void (APIENTRY *CLEARPALETTEFUNCPTR)(GLuint); + + +// New Constants and typedefs for the Texture Object Extension +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 + +// Function prototypes for the Texture Object Extension routines +typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, + const GLboolean *); +typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint); +typedef void (APIENTRY *DELTEXFUNCPTR)(GLsizei, const GLuint *); +typedef void (APIENTRY *GENTEXFUNCPTR)(GLsizei, GLuint *); +typedef GLboolean (APIENTRY *ISTEXFUNCPTR)(GLuint); +typedef void (APIENTRY *PRIORTEXFUNCPTR)(GLsizei, const GLuint *, + const GLclampf *); + + +/* OpenGL ExtEscape escape function constants */ +#ifndef OPENGL_GETINFO +#define OPENGL_GETINFO 4353 /* for OpenGL ExtEscape */ +#endif + +// OPENGL_GETINFO ExtEscape sub-escape numbers. They are defined by +// Microsoft. + +#ifndef OPENGL_GETINFO_DRVNAME + +#define OPENGL_GETINFO_DRVNAME 0 + + +// Input structure for OPENGL_GETINFO ExtEscape. + +typedef struct _OPENGLGETINFO +{ + ULONG ulSubEsc; +} OPENGLGETINFO, *POPENGLGETINFO; + + +// Output structure for OPENGL_GETINFO_DRVNAME ExtEscape. + +typedef struct _GLDRVNAMERET +{ + ULONG ulVersion; // must be 1 for this version + ULONG ulDriverVersion; // driver specific version number + WCHAR awch[MAX_PATH+1]; +} GLDRVNAMERET, *PGLDRVNAMERET; + +#endif + + diff --git a/tools/quake2/extra/qe4/icon1.ico b/tools/quake2/extra/qe4/icon1.ico new file mode 100644 index 0000000000000000000000000000000000000000..d24956b6fe8f7efa2e945a98d72380e6c10ed564 GIT binary patch literal 766 zcmeH_K@P$o6huGOq+3^RW$7*SNZz2_z#~E80XPC(nz%4cV;TbOILO8rZ=myef8bBp z5JVJ9>x~p$8<8!2Pc%6aC2MvO!|b~ZLng*lW9L?!bMzA6wFD?T!YZTE{`%<`;2)^U zD 0x80) + { + rept = (rept^0xff)+2; + b = *source++; + memset(unpacked,b,rept); + unpacked += rept; + } + else if (rept < 0x80) + { + rept++; + memcpy(unpacked,source,rept); + unpacked += rept; + source += rept; + } + else + rept = 0; // rept of 0x80 is NOP + + count += rept; + + } while (countbpwidth) + Error ("Decompression exceeded width!\n"); + + + return source; +} + + +/* +================= +LoadLBM +================= +*/ +void LoadLBM (char *filename, byte **picture, byte **palette) +{ + byte *LBMbuffer, *picbuffer, *cmapbuffer; + int y; + byte *LBM_P, *LBMEND_P; + byte *pic_p; + byte *body_p; + + int formtype,formlength; + int chunktype,chunklength; + +// qiet compiler warnings + picbuffer = NULL; + cmapbuffer = NULL; + +// +// load the LBM +// + LoadFile (filename, (void **)&LBMbuffer); + +// +// parse the LBM header +// + LBM_P = LBMbuffer; + if ( *(int *)LBMbuffer != LittleLong(FORMID) ) + Error ("No FORM ID at start of file!\n"); + + LBM_P += 4; + formlength = BigLong( *(int *)LBM_P ); + LBM_P += 4; + LBMEND_P = LBM_P + Align(formlength); + + formtype = LittleLong(*(int *)LBM_P); + + if (formtype != ILBMID && formtype != PBMID) + Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff + ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff); + + LBM_P += 4; + +// +// parse chunks +// + + while (LBM_P < LBMEND_P) + { + chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24); + LBM_P += 4; + chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24); + LBM_P += 4; + + switch ( chunktype ) + { + case BMHDID: + memcpy (&bmhd,LBM_P,sizeof(bmhd)); + bmhd.w = BigShort(bmhd.w); + bmhd.h = BigShort(bmhd.h); + bmhd.x = BigShort(bmhd.x); + bmhd.y = BigShort(bmhd.y); + bmhd.pageWidth = BigShort(bmhd.pageWidth); + bmhd.pageHeight = BigShort(bmhd.pageHeight); + break; + + case CMAPID: + cmapbuffer = malloc (768); + memset (cmapbuffer, 0, 768); + memcpy (cmapbuffer, LBM_P, chunklength); + break; + + case BODYID: + body_p = LBM_P; + + pic_p = picbuffer = malloc (bmhd.w*bmhd.h); + if (formtype == PBMID) + { + // + // unpack PBM + // + for (y=0 ; ydata; + + pcx->xmin = LittleShort(pcx->xmin); + pcx->ymin = LittleShort(pcx->ymin); + pcx->xmax = LittleShort(pcx->xmax); + pcx->ymax = LittleShort(pcx->ymax); + pcx->hres = LittleShort(pcx->hres); + pcx->vres = LittleShort(pcx->vres); + pcx->bytes_per_line = LittleShort(pcx->bytes_per_line); + pcx->palette_type = LittleShort(pcx->palette_type); + + if (pcx->manufacturer != 0x0a + || pcx->version != 5 + || pcx->encoding != 1 + || pcx->bits_per_pixel != 8 + || pcx->xmax >= 640 + || pcx->ymax >= 480) + Error ("Bad pcx file %s", filename); + + if (palette) + { + *palette = malloc(768); + memcpy (*palette, (byte *)pcx + len - 768, 768); + } + + if (width) + *width = pcx->xmax+1; + if (height) + *height = pcx->ymax+1; + + if (!pic) + return; + + out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) ); + if (!out) + Error ("Skin_Cache: couldn't allocate"); + + *pic = out; + + pix = out; + + for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1) + { + for (x=0 ; x<=pcx->xmax ; ) + { + dataByte = *raw++; + + if((dataByte & 0xC0) == 0xC0) + { + runLength = dataByte & 0x3F; + dataByte = *raw++; + } + else + runLength = 1; + + while(runLength-- > 0) + pix[x++] = dataByte; + } + + } + + if ( raw - (byte *)pcx > len) + Error ("PCX file %s was malformed", filename); + + free (pcx); +} + +/* +============== +WritePCXfile +============== +*/ +void WritePCXfile (char *filename, byte *data, + int width, int height, byte *palette) +{ + int i, j, length; + pcx_t *pcx; + byte *pack; + + pcx = malloc (width*height*2+1000); + memset (pcx, 0, sizeof(*pcx)); + + pcx->manufacturer = 0x0a; // PCX id + pcx->version = 5; // 256 color + pcx->encoding = 1; // uncompressed + pcx->bits_per_pixel = 8; // 256 color + pcx->xmin = 0; + pcx->ymin = 0; + pcx->xmax = LittleShort((short)(width-1)); + pcx->ymax = LittleShort((short)(height-1)); + pcx->hres = LittleShort((short)width); + pcx->vres = LittleShort((short)height); + pcx->color_planes = 1; // chunky image + pcx->bytes_per_line = LittleShort((short)width); + pcx->palette_type = LittleShort(2); // not a grey scale + + // pack the image + pack = &pcx->data; + + for (i=0 ; i=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + else { // non run-length packet + for(j=0;j0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut:; + } + } + + fclose(fin); +} diff --git a/tools/quake2/extra/qe4/lbmlib.h b/tools/quake2/extra/qe4/lbmlib.h new file mode 100644 index 00000000..c90a6dd8 --- /dev/null +++ b/tools/quake2/extra/qe4/lbmlib.h @@ -0,0 +1,40 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// piclib.h + + +void LoadLBM (char *filename, byte **picture, byte **palette); +void WriteLBMfile (char *filename, byte *data, int width, int height + , byte *palette); +void LoadPCX (char *filename, byte **picture, byte **palette, int *width, int *height); +void WritePCXfile (char *filename, byte *data, int width, int height + , byte *palette); + +// loads / saves either lbm or pcx, depending on extension +void Load256Image (char *name, byte **pixels, byte **palette, + int *width, int *height); +void Save256Image (char *name, byte *pixels, byte *palette, + int width, int height); + + +void LoadTGA (char *filename, byte **pixels, int *width, int *height); diff --git a/tools/quake2/extra/qe4/makefile b/tools/quake2/extra/qe4/makefile new file mode 100644 index 00000000..7797ac31 --- /dev/null +++ b/tools/quake2/extra/qe4/makefile @@ -0,0 +1,23 @@ + +TARGETOS=WINNT + +!include + +# This line allows NMAKE to work as well + +all: gengl.exe + +# Update the object file if necessary + +gengl.obj: gengl.c gengl.h + $(cc) $(cflags) $(cvars) $(cdebug) $(cf) gengl.c + +render.obj: render.c gengl.h + $(cc) $(cflags) $(cvars) $(cdebug) $(cf) render.c + +gengl.res: gengl.rc genglrc.h + rc -r gengl.rc + +gengl.exe: gengl.obj gengl.res render.obj + $(link) $(linkdebug) /NODEFAULTLIB $(guilflags) -out:gengl.exe \ + gengl.obj render.obj gengl.res $(guilibsdll) opengl32.lib glu32.lib diff --git a/tools/quake2/extra/qe4/map.c b/tools/quake2/extra/qe4/map.c new file mode 100644 index 00000000..9528e152 --- /dev/null +++ b/tools/quake2/extra/qe4/map.c @@ -0,0 +1,661 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// map.c + +#include "qe3.h" + +qboolean modified; // for quit confirmation (0 = clean, 1 = unsaved, + // 2 = autosaved, but not regular saved) + +char currentmap[1024]; + +brush_t active_brushes; // brushes currently being displayed +brush_t selected_brushes; // highlighted +face_t *selected_face; +brush_t *selected_face_brush; +brush_t filtered_brushes; // brushes that have been filtered or regioned + +entity_t entities; // head/tail of doubly linked list + +entity_t *world_entity; + +void AddRegionBrushes (void); +void RemoveRegionBrushes (void); + +/* +============================================================= + + Cross map selection saving + + this could fuck up if you have only part of a complex entity selected... +============================================================= +*/ + +brush_t between_brushes; +entity_t between_entities; + + +void Map_SaveBetween (void) +{ + brush_t *b; + entity_t *e, *e2; + + between_brushes.next = selected_brushes.next; + between_brushes.prev = selected_brushes.prev; + between_brushes.next->prev = &between_brushes; + between_brushes.prev->next = &between_brushes; + + between_entities.next = between_entities.prev = &between_entities; + selected_brushes.next = selected_brushes.prev = &selected_brushes; + + for (b=between_brushes.next ; b != &between_brushes ; b=b->next) + { + e = b->owner; + if (e == world_entity) + b->owner = NULL; + else + { + for (e2=between_entities.next ; e2 != &between_entities ; e2=e2->next) + if (e2 == e) + goto next; // allready got the entity + // move the entity over + e->prev->next = e->next; + e->next->prev = e->prev; + e->next = between_entities.next; + e->prev = &between_entities; + e->next->prev = e; + e->prev->next = e; + } +next: ; + } +} + +void Map_RestoreBetween (void) +{ + entity_t *head, *tail; + brush_t *b; + + if (!between_brushes.next) + return; + + for (b=between_brushes.next ; b != &between_brushes ; b=b->next) + { + if (!b->owner) + { + b->owner = world_entity; + b->onext = world_entity->brushes.onext; + b->oprev = &world_entity->brushes; + b->onext->oprev = b; + b->oprev->onext = b; + } + } + + selected_brushes.next = between_brushes.next; + selected_brushes.prev = between_brushes.prev; + selected_brushes.next->prev = &selected_brushes; + selected_brushes.prev->next = &selected_brushes; + + head = between_entities.next; + tail = between_entities.prev; + + if (head != tail) + { + entities.prev->next = head; + head->prev = entities.prev; + tail->next = &entities; + entities.prev = tail; + } + + between_brushes.next = NULL; + between_entities.next = NULL; +} + +//============================================================================ + +void Map_BuildBrushData(void) +{ + brush_t *b, *next; + + if (active_brushes.next == NULL) + return; + + Sys_BeginWait (); // this could take a while + + for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=next) + { + next = b->next; + Brush_Build( b ); + if (!b->brush_faces) + { + Brush_Free (b); + Sys_Printf ("Removed degenerate brush\n"); + } + } + + Sys_EndWait(); +} + +entity_t *Map_FindClass (char *cname) +{ + entity_t *ent; + + for (ent = entities.next ; ent != &entities ; ent=ent->next) + { + if (!strcmp(cname, ValueForKey (ent, "classname"))) + return ent; + } + return NULL; +} + +/* +================ +Map_Free +================ +*/ +void Map_Free (void) +{ + if (selected_brushes.next && + (selected_brushes.next != &selected_brushes) ) + { + if (MessageBox(g_qeglobals.d_hwndMain, "Copy selection?", "", MB_YESNO) == IDYES) + Map_SaveBetween (); + } + + Texture_ClearInuse (); + Pointfile_Clear (); + strcpy (currentmap, "unnamed.map"); + Sys_SetTitle (currentmap); + g_qeglobals.d_num_entities = 0; + + if (!active_brushes.next) + { // first map + active_brushes.prev = active_brushes.next = &active_brushes; + selected_brushes.prev = selected_brushes.next = &selected_brushes; + filtered_brushes.prev = filtered_brushes.next = &filtered_brushes; + + entities.prev = entities.next = &entities; + } + else + { + while (active_brushes.next != &active_brushes) + Brush_Free (active_brushes.next); + while (selected_brushes.next != &selected_brushes) + Brush_Free (selected_brushes.next); + while (filtered_brushes.next != &filtered_brushes) + Brush_Free (filtered_brushes.next); + + while (entities.next != &entities) + Entity_Free (entities.next); + } + + world_entity = NULL; +} + +/* +================ +Map_LoadFile +================ +*/ +void Map_LoadFile (char *filename) +{ + char *buf; + entity_t *ent; + char temp[1024]; + + Sys_BeginWait (); + + SetInspectorMode(W_CONSOLE); + + QE_ConvertDOSToUnixName( temp, filename ); + Sys_Printf ("Map_LoadFile: %s\n", temp ); + + Map_Free (); + + g_qeglobals.d_parsed_brushes = 0; + strcpy (currentmap, filename); + LoadFile (filename, (void **)&buf); + + StartTokenParsing (buf); + + g_qeglobals.d_num_entities = 0; + + while (1) + { + ent = Entity_Parse (false); + if (!ent) + break; + if (!strcmp(ValueForKey (ent, "classname"), "worldspawn")) + { + if (world_entity) + Sys_Printf ("WARNING: multiple worldspawn\n"); + world_entity = ent; + } + else + { + // add the entity to the end of the entity list + ent->next = &entities; + ent->prev = entities.prev; + entities.prev->next = ent; + entities.prev = ent; + g_qeglobals.d_num_entities++; + } + } + + free (buf); + + if (!world_entity) + { + Sys_Printf ("No worldspawn in map.\n"); + Map_New (); + return; + } + + Sys_Printf ("--- LoadMapFile ---\n"); + Sys_Printf ("%s\n", temp ); + + Sys_Printf ("%5i brushes\n", g_qeglobals.d_parsed_brushes ); + Sys_Printf ("%5i entities\n", g_qeglobals.d_num_entities); + + Map_RestoreBetween (); + + Sys_Printf ("Map_BuildAllDisplayLists\n"); + Map_BuildBrushData(); + + // + // move the view to a start position + // + ent = Map_FindClass ("info_player_start"); + if (!ent) + ent = Map_FindClass ("info_player_deathmatch"); + camera.angles[PITCH] = 0; + if (ent) + { + GetVectorForKey (ent, "origin", camera.origin); + GetVectorForKey (ent, "origin", g_qeglobals.d_xy.origin); + camera.angles[YAW] = FloatForKey (ent, "angle"); + } + else + { + camera.angles[YAW] = 0; + VectorCopy (vec3_origin, camera.origin); + VectorCopy (vec3_origin, g_qeglobals.d_xy.origin); + } + + Sys_UpdateWindows (W_ALL); + + Map_RegionOff (); + + modified = false; + Sys_SetTitle (temp); + + Texture_ShowInuse (); + + Sys_EndWait(); + +} + +/* +=========== +Map_SaveFile +=========== +*/ +void Map_SaveFile (char *filename, qboolean use_region ) +{ + entity_t *e, *next; + FILE *f; + char temp[1024]; + int count; + + QE_ConvertDOSToUnixName( temp, filename ); + + if (!use_region) + { + char backup[1024]; + + // rename current to .bak + strcpy (backup, filename); + StripExtension (backup); + strcat (backup, ".bak"); + _unlink (backup); + rename (filename, backup); + } + + Sys_Printf ("Map_SaveFile: %s\n", filename); + + f = fopen(filename, "w"); + if (!f) + { + Sys_Printf ("ERROR!!!! Couldn't open %s\n", filename); + return; + } + + if (use_region) + AddRegionBrushes (); + + // write world entity first + Entity_Write (world_entity, f, use_region); + + // then write all other ents + count = 1; + for (e=entities.next ; e != &entities ; e=next) + { + fprintf (f, "// entity %i\n", count); + count++; + next = e->next; + if (e->brushes.onext == &e->brushes) + Entity_Free (e); // no brushes left, so remove it + else + Entity_Write (e, f, use_region); + } + + fclose (f); + + if (use_region) + RemoveRegionBrushes (); + + Sys_Printf ("Saved.\n"); + modified = false; + + if ( !strstr( temp, "autosave" ) ) + Sys_SetTitle (temp); + + if (!use_region) + { + time_t timer; + FILE *f; + + time (&timer); + MessageBeep (MB_ICONEXCLAMATION); + f = fopen ("c:/tstamps.log", "a"); + if (f) + { + fprintf (f, "%4i : %35s : %s", g_qeglobals.d_workcount, filename, ctime(&timer)); + fclose (f); + g_qeglobals.d_workcount = 0; + } + fclose (f); + Sys_Status ("Saved.\n", 0); + } +} + +/* +=========== +Map_New +=========== +*/ +void Map_New (void) +{ + Sys_Printf ("Map_New\n"); + Map_Free (); + world_entity = qmalloc(sizeof(*world_entity)); + world_entity->brushes.onext = + world_entity->brushes.oprev = &world_entity->brushes; + SetKeyValue (world_entity, "classname", "worldspawn"); + world_entity->eclass = Eclass_ForName ("worldspawn", true); + + camera.angles[YAW] = 0; + VectorCopy (vec3_origin, camera.origin); + camera.origin[2] = 48; + VectorCopy (vec3_origin, g_qeglobals.d_xy.origin); + + Map_RestoreBetween (); + + Sys_UpdateWindows (W_ALL); + modified = false; +} + + +/* +=========================================================== + + REGION + +=========================================================== +*/ + +qboolean region_active; +vec3_t region_mins = {-4096, -4096, -4096}; +vec3_t region_maxs = {4096, 4096, 4096}; + +brush_t *region_sides[4]; + +/* +=========== +AddRegionBrushes + +a regioned map will have temp walls put up at the region boundary +=========== +*/ +void AddRegionBrushes (void) +{ + vec3_t mins, maxs; + int i; + texdef_t td; + + if (!region_active) + return; + + memset (&td, 0, sizeof(td)); + strcpy (td.name, "REGION"); + + mins[0] = region_mins[0] - 16; + maxs[0] = region_mins[0] + 1; + mins[1] = region_mins[1] - 16; + maxs[1] = region_maxs[1] + 16; + mins[2] = -2048; + maxs[2] = 2048; + region_sides[0] = Brush_Create (mins, maxs, &td); + + mins[0] = region_maxs[0] - 1; + maxs[0] = region_maxs[0] + 16; + region_sides[1] = Brush_Create (mins, maxs, &td); + + mins[0] = region_mins[0] - 16; + maxs[0] = region_maxs[0] + 16; + mins[1] = region_mins[1] - 16; + maxs[1] = region_mins[1] + 1; + region_sides[2] = Brush_Create (mins, maxs, &td); + + mins[1] = region_maxs[1] - 1; + maxs[1] = region_maxs[1] + 16; + region_sides[3] = Brush_Create (mins, maxs, &td); + + for (i=0 ; i<4 ; i++) + { + Brush_AddToList (region_sides[i], &selected_brushes); + Entity_LinkBrush (world_entity, region_sides[i]); + Brush_Build( region_sides[i] ); + } +} + +void RemoveRegionBrushes (void) +{ + int i; + + if (!region_active) + return; + for (i=0 ; i<4 ; i++) + Brush_Free (region_sides[i]); +} + + +qboolean Map_IsBrushFiltered (brush_t *b) +{ + int i; + + for (i=0 ; i<3 ; i++) + { + if (b->mins[i] > region_maxs[i]) + return true; + if (b->maxs[i] < region_mins[i]) + return true; + } + return false; +} + +/* +=========== +Map_RegionOff + +Other filtering options may still be on +=========== +*/ +void Map_RegionOff (void) +{ + brush_t *b, *next; + int i; + + region_active = false; + for (i=0 ; i<3 ; i++) + { + region_maxs[i] = 4096; + region_mins[i] = -4096; + } + + for (b=filtered_brushes.next ; b != &filtered_brushes ; b=next) + { + next = b->next; + if (Map_IsBrushFiltered (b)) + continue; // still filtered + Brush_RemoveFromList (b); + Brush_AddToList (b, &active_brushes); + } + + Sys_UpdateWindows (W_ALL); +} + +void Map_ApplyRegion (void) +{ + brush_t *b, *next; + + region_active = true; + for (b=active_brushes.next ; b != &active_brushes ; b=next) + { + next = b->next; + if (!Map_IsBrushFiltered (b)) + continue; // still filtered + Brush_RemoveFromList (b); + Brush_AddToList (b, &filtered_brushes); + } + + Sys_UpdateWindows (W_ALL); +} + + +/* +======================== +Map_RegionSelectedBrushes +======================== +*/ +void Map_RegionSelectedBrushes (void) +{ + Map_RegionOff (); + + region_active = true; + Select_GetBounds (region_mins, region_maxs); + + // move the entire active_brushes list to filtered_brushes + filtered_brushes.next = active_brushes.next; + filtered_brushes.prev = active_brushes.prev; + filtered_brushes.next->prev = &filtered_brushes; + filtered_brushes.prev->next = &filtered_brushes; + + // move the entire selected_brushes list to active_brushes + active_brushes.next = selected_brushes.next; + active_brushes.prev = selected_brushes.prev; + active_brushes.next->prev = &active_brushes; + active_brushes.prev->next = &active_brushes; + + // clear selected_brushes + selected_brushes.next = selected_brushes.prev = &selected_brushes; + + Sys_UpdateWindows (W_ALL); +} + + +/* +=========== +Map_RegionXY +=========== +*/ +void Map_RegionXY (void) +{ + Map_RegionOff (); + + region_mins[0] = g_qeglobals.d_xy.origin[0] - 0.5*g_qeglobals.d_xy.width/g_qeglobals.d_xy.scale; + region_maxs[0] = g_qeglobals.d_xy.origin[0] + 0.5*g_qeglobals.d_xy.width/g_qeglobals.d_xy.scale; + region_mins[1] = g_qeglobals.d_xy.origin[1] - 0.5*g_qeglobals.d_xy.height/g_qeglobals.d_xy.scale; + region_maxs[1] = g_qeglobals.d_xy.origin[1] + 0.5*g_qeglobals.d_xy.height/g_qeglobals.d_xy.scale; + region_mins[2] = -4096; + region_maxs[2] = 4096; + + Map_ApplyRegion (); +} + +/* +=========== +Map_RegionTallBrush +=========== +*/ +void Map_RegionTallBrush (void) +{ + brush_t *b; + + if (!QE_SingleBrush ()) + return; + + b = selected_brushes.next; + + Map_RegionOff (); + + VectorCopy (b->mins, region_mins); + VectorCopy (b->maxs, region_maxs); + region_mins[2] = -4096; + region_maxs[2] = 4096; + + Select_Delete (); + Map_ApplyRegion (); +} +/* +=========== +Map_RegionBrush +=========== +*/ +void Map_RegionBrush (void) +{ + brush_t *b; + + if (!QE_SingleBrush ()) + return; + + b = selected_brushes.next; + + Map_RegionOff (); + + VectorCopy (b->mins, region_mins); + VectorCopy (b->maxs, region_maxs); + + Select_Delete (); + Map_ApplyRegion (); +} + diff --git a/tools/quake2/extra/qe4/map.h b/tools/quake2/extra/qe4/map.h new file mode 100644 index 00000000..58d9ed75 --- /dev/null +++ b/tools/quake2/extra/qe4/map.h @@ -0,0 +1,53 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// map.h -- the state of the current world that all views are displaying + +extern char currentmap[1024]; + +// head/tail of doubly linked lists +extern brush_t active_brushes; // brushes currently being displayed +extern brush_t selected_brushes; // highlighted +extern face_t *selected_face; +extern brush_t *selected_face_brush; +extern brush_t filtered_brushes; // brushes that have been filtered or regioned + +extern entity_t entities; +extern entity_t *world_entity; // the world entity is NOT included in + // the entities chain + +extern qboolean modified; // for quit confirmations + +extern vec3_t region_mins, region_maxs; +extern qboolean region_active; + +void Map_LoadFile (char *filename); +void Map_SaveFile (char *filename, qboolean use_region); +void Map_New (void); +void Map_BuildBrushData(void); + +void Map_RegionOff (void); +void Map_RegionXY (void); +void Map_RegionTallBrush (void); +void Map_RegionBrush (void); +void Map_RegionSelectedBrushes (void); +qboolean Map_IsBrushFiltered (brush_t *b); diff --git a/tools/quake2/extra/qe4/mathlib.c b/tools/quake2/extra/qe4/mathlib.c new file mode 100644 index 00000000..d430ff70 --- /dev/null +++ b/tools/quake2/extra/qe4/mathlib.c @@ -0,0 +1,131 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// mathlib.c -- math primitives + +#include "cmdlib.h" +#include "mathlib.h" + +vec3_t vec3_origin = {0.0f,0.0f,0.0f}; + + +float VectorLength(vec3_t v) +{ + int i; + float length; + + length = 0.0f; + for (i=0 ; i< 3 ; i++) + length += v[i]*v[i]; + length = (float)sqrt (length); + + return length; +} + +qboolean VectorCompare (vec3_t v1, vec3_t v2) +{ + int i; + + for (i=0 ; i<3 ; i++) + if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON) + return false; + + return true; +} + +vec_t Q_rint (vec_t in) +{ + return (float)floor (in + 0.5); +} + +void VectorMA (vec3_t va, float scale, vec3_t vb, vec3_t vc) +{ + vc[0] = va[0] + scale*vb[0]; + vc[1] = va[1] + scale*vb[1]; + vc[2] = va[2] + scale*vb[2]; +} + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +{ + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +vec_t _DotProduct (vec3_t v1, vec3_t v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out) +{ + out[0] = va[0]-vb[0]; + out[1] = va[1]-vb[1]; + out[2] = va[2]-vb[2]; +} + +void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out) +{ + out[0] = va[0]+vb[0]; + out[1] = va[1]+vb[1]; + out[2] = va[2]+vb[2]; +} + +void _VectorCopy (vec3_t in, vec3_t out) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +vec_t VectorNormalize (vec3_t v) +{ + int i; + float length; + + length = 0.0f; + for (i=0 ; i< 3 ; i++) + length += v[i]*v[i]; + length = (float)sqrt (length); + if (length == 0) + return (vec_t)0; + + for (i=0 ; i< 3 ; i++) + v[i] /= length; + + return length; +} + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void VectorScale (vec3_t v, vec_t scale, vec3_t out) +{ + out[0] = v[0] * scale; + out[1] = v[1] * scale; + out[2] = v[2] * scale; +} + diff --git a/tools/quake2/extra/qe4/mathlib.h b/tools/quake2/extra/qe4/mathlib.h new file mode 100644 index 00000000..2569bed5 --- /dev/null +++ b/tools/quake2/extra/qe4/mathlib.h @@ -0,0 +1,66 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#ifndef __MATHLIB__ +#define __MATHLIB__ + +// mathlib.h + +#include + +typedef float vec_t; +typedef vec_t vec3_t[3]; + +#define SIDE_FRONT 0 +#define SIDE_ON 2 +#define SIDE_BACK 1 +#define SIDE_CROSS -2 + +#define Q_PI 3.14159265358979323846 + +extern vec3_t vec3_origin; + +#define EQUAL_EPSILON 0.001 + +qboolean VectorCompare (vec3_t v1, vec3_t v2); + +#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) +#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];} +#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];} +#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];} + +vec_t Q_rint (vec_t in); +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out); +void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out); +void _VectorCopy (vec3_t in, vec3_t out); + +float VectorLength(vec3_t v); + +void VectorMA (vec3_t va, float scale, vec3_t vb, vec3_t vc); + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +vec_t VectorNormalize (vec3_t v); +void VectorInverse (vec3_t v); +void VectorScale (vec3_t v, vec_t scale, vec3_t out); + +#endif diff --git a/tools/quake2/extra/qe4/mru.c b/tools/quake2/extra/qe4/mru.c new file mode 100644 index 00000000..84a5a3eb --- /dev/null +++ b/tools/quake2/extra/qe4/mru.c @@ -0,0 +1,671 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +//************************************************************* +// File name: mru.c +// +// Description: +// +// Routines for MRU support +// +// Development Team: +// +// Gilles Vollant (100144.2636@compuserve.com) +// +//************************************************************* + +#include +#include +#include + +#include "mru.h" +// CreateMruMenu : MRUMENU constructor +// wNbLruShowInit : nb of item showed in menu +// wNbLruMenuInit : nb of item stored in memory +// wMaxSizeLruItemInit : size max. of filename + + +//************************************************************* +// +// CreateMruMenu() +// +// Purpose: +// +// Allocate and Initialize an MRU and return a pointer on it +// +// +// Parameters: +// +// WORD wNbLruShowInit - Maximum number of item displayed on menu +// WORD wNbLruMenuInit - Maximum number of item stored in memory +// WORD wMaxSizeLruItemInit - Maximum size of an item (ie size of pathname) +// WORD wIdMruInit - ID of the first item in the menu (default:IDMRU) +// +// +// Return: (LPMRUMENU) +// +// Pointer on a MRUMENU structure, used by other function +// +// +// Comments: +// wNbLruShowInit <= wNbLruMenuInit +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* + +LPMRUMENU CreateMruMenu (WORD wNbLruShowInit, + WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit) +{ +LPMRUMENU lpMruMenu; + lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU)); + + lpMruMenu->wNbItemFill = 0; + lpMruMenu->wNbLruMenu = wNbLruMenuInit; + lpMruMenu->wNbLruShow = wNbLruShowInit; + lpMruMenu->wIdMru = wIdMruInit; + lpMruMenu->wMaxSizeLruItem = wMaxSizeLruItemInit; + lpMruMenu->lpMRU = (LPSTR)GlobalAllocPtr(GHND, + lpMruMenu->wNbLruMenu*(UINT)lpMruMenu->wMaxSizeLruItem); + if (lpMruMenu->lpMRU == NULL) + { + GlobalFreePtr(lpMruMenu); + lpMruMenu = NULL; + } + return lpMruMenu; +} + +//************************************************************* +// +// CreateMruMenuDefault() +// +// Purpose: +// +// Allocate and Initialize an MRU and return a pointer on it +// Use default parameter +// +// +// Parameters: +// +// +// Return: (LPMRUMENU) +// +// Pointer on a MRUMENU structure, used by other function +// +// +// Comments: +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* + +LPMRUMENU CreateMruMenuDefault() +{ + return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU); +} + + +//************************************************************* +// +// DeleteMruMenu() +// +// Purpose: +// Destructor : +// Clean and free a MRUMENU structure +// +// Parameters: +// +// LPMRUMENU lpMruMenu - pointer on MRUMENU, allocated +// by CreateMruMenu() or CreateMruMenuDefault() +// +// +// Return: void +// +// +// Comments: +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void DeleteMruMenu(LPMRUMENU lpMruMenu) +{ + GlobalFreePtr(lpMruMenu->lpMRU); + GlobalFreePtr(lpMruMenu); +} + +//************************************************************* +// +// SetNbLruShow() +// +// Purpose: +// Change the maximum number of item displayed on menu +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wNbLruShowInit - Maximum number of item displayed on menu +// +// +// Return: void +// +// +// Comments: +// +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit) +{ + lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu); +} + +//************************************************************* +// +// SetMenuItem() +// +// Purpose: +// Set the filename of an item +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wItem - Number of Item to set, zero based +// LPSTR lpItem - String, contain the filename of the item +// +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// used when load .INI or reg database +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem) +{ + if (wItem >= NBMRUMENU) + return FALSE; + _fstrncpy((lpMruMenu->lpMRU) + + ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem), + lpItem,lpMruMenu->wMaxSizeLruItem-1); + lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1); + return TRUE; +} + +//************************************************************* +// +// GetMenuItem() +// +// Purpose: +// Get the filename of an item +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wItem - Number of Item to set, zero based +// BOOL fIDMBased - TRUE : wItem is based on ID menu item +// FALSE : wItem is zero-based +// LPSTR lpItem - String where the filename of the item will be +// stored by GetMenuItem() +// UINT uiSize - Size of the lpItem buffer +// +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Used for saving in .INI or reg database, or when user select +// an MRU in File menu +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, + BOOL fIDMBased,LPSTR lpItem,UINT uiSize) +{ + if (fIDMBased) + wItem -= (lpMruMenu->wIdMru + 1); + if (wItem >= lpMruMenu->wNbItemFill) + return FALSE; + _fstrncpy(lpItem,(lpMruMenu->lpMRU) + + ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize); + *(lpItem+uiSize-1) = '\0'; + return TRUE; +} + +//************************************************************* +// +// AddNewItem() +// +// Purpose: +// Add an item at the begin of the list +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpItem - String contain the filename to add +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Used when used open a file (using File Open common +// dialog, Drag and drop or MRU) +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem) +{ +WORD i,j; + for (i=0;iwNbItemFill;i++) + if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) + + ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0) + { + // Shift the other items + for (j=i;j>0;j--) + lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j), + (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1))); + _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1); + return ; + } + lpMruMenu->wNbItemFill = min(lpMruMenu->wNbItemFill+1,lpMruMenu->wNbLruMenu); + for (i=lpMruMenu->wNbItemFill-1;i>0;i--) + lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i), + lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i-1))); + _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1); +} + +//************************************************************* +// +// DelMenuItem() +// +// Purpose: +// Delete an item +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// WORD wItem - Number of Item to set, zero based +// BOOL fIDMBased - TRUE : wItem is based on ID menu item +// FALSE : wItem is zero-based +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Used when used open a file, using MRU, and when an error +// occured (by example, when file was deleted) +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased) +{ +WORD i; + if (fIDMBased) + wItem -= (lpMruMenu->wIdMru + 1); + if (lpMruMenu->wNbItemFill <= wItem) + return FALSE; + lpMruMenu->wNbItemFill--; + for (i=wItem;iwNbItemFill;i++) + lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i), + lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i+1))); + return TRUE; +} + +//************************************************************* +// +// PlaceMenuMRUItem() +// +// Purpose: +// Add MRU at the end of a menu +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// HMENU hMenu - Handle of menu where MRU must be added +// UINT uiItem - Item of menu entry where MRU must be added +// +// Return: void +// +// +// Comments: +// Used MRU is modified, for refresh the File menu +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem) +{ +int i; +WORD wNbShow; + if (hMenu == NULL) + return; + // remove old MRU in menu + for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++) + RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND); + + if (lpMruMenu->wNbItemFill == 0) + return; + + // If they are item, insert a separator before the files + InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL); + + wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow); + for (i=(int)wNbShow-1;i>=0;i--) + { + LPSTR lpTxt; + if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20)) + { + wsprintf(lpTxt,"&%lu %s", + (DWORD)(i+1),lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem*(UINT)i)); + InsertMenu(hMenu,(((WORD)i)!=(wNbShow-1)) ? (lpMruMenu->wIdMru+i+2) : lpMruMenu->wIdMru, + MF_STRING,lpMruMenu->wIdMru+i+1,lpTxt); + GlobalFreePtr(lpTxt); + } + } + +} + +/////////////////////////////////////////// + + + +//************************************************************* +// +// SaveMruInIni() +// +// Purpose: +// Save MRU in a private .INI +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszSection - Points to a null-terminated string containing +// the name of the section +// LPSTR lpszFile - Points to a null-terminated string that names +// the initialization file. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// See WritePrivateProfileString API for more info on lpszSection and lpszFile +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile) +{ +LPSTR lpTxt; +WORD i; + + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + wsprintf(szEntry,"File%lu",(DWORD)i+1); + if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10)) + *lpTxt = '\0'; + WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile); + } + GlobalFreePtr(lpTxt); + WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache + return TRUE; +} + + +//************************************************************* +// +// LoadMruInIni() +// +// Purpose: +// Load MRU from a private .INI +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszSection - Points to a null-terminated string containing +// the name of the section +// LPSTR lpszFile - Points to a null-terminated string that names +// the initialization file. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// See GetPrivateProfileString API for more info on lpszSection and lpszFile +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile) +{ +LPSTR lpTxt; +WORD i; + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + + wsprintf(szEntry,"File%lu",(DWORD)i+1); + GetPrivateProfileString(lpszSection,szEntry,"",lpTxt, + lpMruMenu->wMaxSizeLruItem + 10,lpszFile); + if (*lpTxt == '\0') + break; + SetMenuItem(lpMruMenu,i,lpTxt); + } + GlobalFreePtr(lpTxt); + return TRUE; +} + +#ifdef WIN32 + +BOOL IsWin395OrHigher(void) +{ + WORD wVer; + + wVer = LOWORD(GetVersion()); + wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer); + + return (wVer >= 0x035F); // 5F = 95 dec +} + + +//************************************************************* +// +// SaveMruInReg() +// +// Purpose: +// Save MRU in the registry +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszKey - Points to a null-terminated string +// specifying the name of a key that +// this function opens or creates. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Win32 function designed for Windows NT and Windows 95 +// See RegCreateKeyEx API for more info on lpszKey +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey) +{ +LPSTR lpTxt; +WORD i; +HKEY hCurKey; +DWORD dwDisp; + + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL, + REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp); + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + wsprintf(szEntry,"File%lu",(DWORD)i+1); + if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10)) + *lpTxt = '\0'; + RegSetValueEx(hCurKey,szEntry,0,REG_SZ,lpTxt,lstrlen(lpTxt)); + } + RegCloseKey(hCurKey); + GlobalFreePtr(lpTxt); + return TRUE; +} + +//************************************************************* +// +// LoadMruInReg() +// +// Purpose: +// Load MRU from the registry +// +// Parameters: +// LPMRUMENU lpMruMenu - pointer on MRUMENU +// LPSTR lpszKey - Points to a null-terminated string +// specifying the name of a key that +// this function opens or creates. +// +// Return: (BOOL) +// TRUE - Function run successfully +// FALSE - Function don't run successfully +// +// +// Comments: +// Win32 function designed for Windows NT and Windows 95 +// See RegOpenKeyEx API for more info on lpszKey +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey) +{ +LPSTR lpTxt; +WORD i; +HKEY hCurKey; +DWORD dwType; + lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); + if (lpTxt == NULL) + return FALSE; + + RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey); + + + for (i=0;iwNbLruMenu;i++) + { + char szEntry[16]; + DWORD dwSizeBuf; + wsprintf(szEntry,"File%lu",(DWORD)i+1); + *lpTxt = '\0'; + dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10; + RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf); + *(lpTxt+dwSizeBuf)='\0'; + if (*lpTxt == '\0') + break; + SetMenuItem(lpMruMenu,i,lpTxt); + } + RegCloseKey(hCurKey); + GlobalFreePtr(lpTxt); + return TRUE; +} + + +//************************************************************* +// +// GetWin32Kind() +// +// Purpose: +// Get the Win32 platform +// +// Parameters: +// +// Return: (WIN32KIND) +// WINNT - Run under Windows NT +// WIN32S - Run under Windows 3.1x + Win32s +// WIN95ORGREATHER - Run under Windows 95 +// +// +// Comments: +// Win32 function designed for Windows NT and Windows 95 +// See RegOpenKeyEx API for more info on lpszKey +// +// History: Date Author Comment +// 09/24/94 G. Vollant Created +// +//************************************************************* +WIN32KIND GetWin32Kind() +{ +BOOL IsWin395OrHigher(void); + + WORD wVer; + + if ((GetVersion() & 0x80000000) == 0) + return WINNT; + wVer = LOWORD(GetVersion()); + wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer); + + if (wVer >= 0x035F) + return WIN95ORGREATHER; + else + return WIN32S; +} +#endif diff --git a/tools/quake2/extra/qe4/mru.h b/tools/quake2/extra/qe4/mru.h new file mode 100644 index 00000000..b78b986c --- /dev/null +++ b/tools/quake2/extra/qe4/mru.h @@ -0,0 +1,101 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +//************************************************************* +// File name: mru.h +// +// Description: +// +// Header for MRU support +// +// Development Team: +// +// Gilles Vollant (100144.2636@compuserve.com) +// +//************************************************************* + +#ifndef __MRU_H__ +#define __MRU_H__ + +#define NBMRUMENUSHOW 6 // Default number of MRU showed in the menu File +#define NBMRUMENU 9 // Default number of MRU stored +#define IDMRU 8000 // Default First ID of MRU +#ifdef OFS_MAXPATHNAME +#define MAXSIZEMRUITEM OFS_MAXPATHNAME +#else +#define MAXSIZEMRUITEM 128 // Default max size of an entry +#endif + +typedef struct +{ +WORD wNbItemFill; +WORD wNbLruShow; +WORD wNbLruMenu; +WORD wMaxSizeLruItem; +WORD wIdMru; +LPSTR lpMRU; +} MRUMENU; + +typedef MRUMENU FAR * LPMRUMENU; + +#ifdef __cplusplus +LPMRUMENU CreateMruMenu (WORD wNbLruShowInit=NBMRUMENUSHOW, + WORD wNbLruMenuInit=NBMRUMENU, + WORD wMaxSizeLruItemInit=MAXSIZEMRUITEM, + WORD wIdMruInit=IDMRU); +#else +LPMRUMENU CreateMruMenu (WORD wNbLruShowInit, + WORD wNbLruMenuInit, + WORD wMaxSizeLruItemInit, + WORD wIdMruInit); +#endif + +LPMRUMENU CreateMruMenuDefault(); +void DeleteMruMenu (LPMRUMENU lpMruMenu); + +void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit); +BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, + LPSTR lpItem); +BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, + BOOL fIDMBased,LPSTR lpItem,UINT uiSize); +BOOL DelMenuItem (LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased); +void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem); +void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem); + +BOOL SaveMruInIni (LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile); +BOOL LoadMruInIni (LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile); +#ifdef WIN32 +BOOL SaveMruInReg (LPMRUMENU lpMruMenu,LPSTR lpszKey); +BOOL LoadMruInReg (LPMRUMENU lpMruMenu,LPSTR lpszKey); + +typedef enum +{ +WIN32S, +WINNT, +WIN95ORGREATHER +} WIN32KIND; +WIN32KIND GetWin32Kind(); +#endif + + +////////////////////////////////////////////////////////////// +#endif diff --git a/tools/quake2/extra/qe4/parse.c b/tools/quake2/extra/qe4/parse.c new file mode 100644 index 00000000..8258a4ad --- /dev/null +++ b/tools/quake2/extra/qe4/parse.c @@ -0,0 +1,141 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +char token[MAXTOKEN]; +qboolean unget; +char *script_p; +int scriptline; + +void StartTokenParsing (char *data) +{ + scriptline = 1; + script_p = data; + unget = false; +} + +qboolean GetToken (qboolean crossline) +{ + char *token_p; + + if (unget) // is a token allready waiting? + return true; + +// +// skip space +// +skipspace: + while (*script_p <= 32) + { + if (!*script_p) + { + if (!crossline) + Error ("Line %i is incomplete",scriptline); + return false; + } + if (*script_p++ == '\n') + { + if (!crossline) + Error ("Line %i is incomplete",scriptline); + scriptline++; + } + } + + if (script_p[0] == '/' && script_p[1] == '/') // comment field + { + if (!crossline) + Error ("Line %i is incomplete\n",scriptline); + while (*script_p++ != '\n') + if (!*script_p) + { + if (!crossline) + Error ("Line %i is incomplete",scriptline); + return false; + } + goto skipspace; + } + +// +// copy token +// + token_p = token; + + if (*script_p == '"') + { + script_p++; + while ( *script_p != '"' ) + { + if (!*script_p) + Error ("EOF inside quoted token"); + *token_p++ = *script_p++; + if (token_p == &token[MAXTOKEN]) + Error ("Token too large on line %i",scriptline); + } + script_p++; + } + else while ( *script_p > 32 ) + { + *token_p++ = *script_p++; + if (token_p == &token[MAXTOKEN]) + Error ("Token too large on line %i",scriptline); + } + + *token_p = 0; + + return true; +} + +void UngetToken (void) +{ + unget = true; +} + + +/* +============== +TokenAvailable + +Returns true if there is another token on the line +============== +*/ +qboolean TokenAvailable (void) +{ + char *search_p; + + search_p = script_p; + + while ( *search_p <= 32) + { + if (*search_p == '\n') + return false; + if (*search_p == 0) + return false; + search_p++; + } + + if (*search_p == ';') + return false; + + return true; +} + diff --git a/tools/quake2/extra/qe4/parse.h b/tools/quake2/extra/qe4/parse.h new file mode 100644 index 00000000..0d5d3e1c --- /dev/null +++ b/tools/quake2/extra/qe4/parse.h @@ -0,0 +1,34 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// parse.h -- text file parsing routines + +#define MAXTOKEN 1024 + +extern char token[MAXTOKEN]; +extern int scriptline; + +void StartTokenParsing (char *data); +qboolean GetToken (qboolean crossline); +void UngetToken (void); +qboolean TokenAvailable (void); + diff --git a/tools/quake2/extra/qe4/points.c b/tools/quake2/extra/qe4/points.c new file mode 100644 index 00000000..deaae483 --- /dev/null +++ b/tools/quake2/extra/qe4/points.c @@ -0,0 +1,155 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + + +#define MAX_POINTFILE 8192 +static vec3_t s_pointvecs[MAX_POINTFILE]; +static int s_num_points, s_check_point; + +void Pointfile_Delete (void) +{ + char name[1024]; + + strcpy (name, currentmap); + StripExtension (name); + strcat (name, ".lin"); + + remove(name); +} + +// advance camera to next point +void Pointfile_Next (void) +{ + vec3_t dir; + + if (s_check_point >= s_num_points-2) + { + Sys_Status ("End of pointfile", 0); + return; + } + s_check_point++; + VectorCopy (s_pointvecs[s_check_point], camera.origin); + VectorCopy (s_pointvecs[s_check_point], g_qeglobals.d_xy.origin); + VectorSubtract (s_pointvecs[s_check_point+1], camera.origin, dir); + VectorNormalize (dir); + camera.angles[1] = atan2 (dir[1], dir[0])*180/3.14159; + camera.angles[0] = asin (dir[2])*180/3.14159; + + Sys_UpdateWindows (W_ALL); +} + +// advance camera to previous point +void Pointfile_Prev (void) +{ + vec3_t dir; + + if ( s_check_point == 0) + { + Sys_Status ("Start of pointfile", 0); + return; + } + s_check_point--; + VectorCopy (s_pointvecs[s_check_point], camera.origin); + VectorCopy (s_pointvecs[s_check_point], g_qeglobals.d_xy.origin); + VectorSubtract (s_pointvecs[s_check_point+1], camera.origin, dir); + VectorNormalize (dir); + camera.angles[1] = atan2 (dir[1], dir[0])*180/3.14159; + camera.angles[0] = asin (dir[2])*180/3.14159; + + Sys_UpdateWindows (W_ALL); +} + +void Pointfile_Check (void) +{ + char name[1024]; + FILE *f; + vec3_t v; + + strcpy (name, currentmap); + StripExtension (name); + strcat (name, ".lin"); + + f = fopen (name, "r"); + if (!f) + return; + + Sys_Printf ("Reading pointfile %s\n", name); + + if (!g_qeglobals.d_pointfile_display_list) + g_qeglobals.d_pointfile_display_list = glGenLists(1); + + s_num_points = 0; + glNewList (g_qeglobals.d_pointfile_display_list, GL_COMPILE); + glColor3f (1, 0, 0); + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_1D); + glLineWidth (4); + glBegin(GL_LINE_STRIP); + do + { + if (fscanf (f, "%f %f %f\n", &v[0], &v[1], &v[2]) != 3) + break; + if (s_num_points < MAX_POINTFILE) + { + VectorCopy (v, s_pointvecs[s_num_points]); + s_num_points++; + } + glVertex3fv (v); + } while (1); + glEnd(); + glLineWidth (1); + glEndList (); + + s_check_point = 0; + fclose (f); + Pointfile_Next (); +} + +void Pointfile_Draw( void ) +{ + int i; + + glColor3f( 1.0F, 0.0F, 0.0F ); + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_1D); + glLineWidth (4); + glBegin(GL_LINE_STRIP); + for ( i = 0; i < s_num_points; i++ ) + { + glVertex3fv( s_pointvecs[i] ); + } + glEnd(); + glLineWidth( 1 ); +} + +void Pointfile_Clear (void) +{ + if (!g_qeglobals.d_pointfile_display_list) + return; + + glDeleteLists (g_qeglobals.d_pointfile_display_list, 1); + g_qeglobals.d_pointfile_display_list = 0; + Sys_UpdateWindows (W_ALL); +} + diff --git a/tools/quake2/extra/qe4/q.bmp b/tools/quake2/extra/qe4/q.bmp new file mode 100644 index 0000000000000000000000000000000000000000..598971a27f28da3e04d05e2847c615a612f9fac5 GIT binary patch literal 13878 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 literal 0 HcmV?d00001 diff --git a/tools/quake2/extra/qe4/qe3.c b/tools/quake2/extra/qe4/qe3.c new file mode 100644 index 00000000..153640d1 --- /dev/null +++ b/tools/quake2/extra/qe4/qe3.c @@ -0,0 +1,451 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +QEGlobals_t g_qeglobals; + +void QE_CheckOpenGLForErrors(void) +{ + int i; + + while ( ( i = glGetError() ) != GL_NO_ERROR ) + { + char buffer[100]; + + sprintf( buffer, "OpenGL Error: %s", gluErrorString( i ) ); + + MessageBox( g_qeglobals.d_hwndMain, buffer , "QuakeEd Error", MB_OK | MB_ICONEXCLAMATION ); + exit( 1 ); + } +} + + +char *ExpandReletivePath (char *p) +{ + static char temp[1024]; + char *base; + + if (!p || !p[0]) + return NULL; + if (p[0] == '/' || p[0] == '\\') + return p; + + base = ValueForKey(g_qeglobals.d_project_entity, "basepath"); + sprintf (temp, "%s/%s", base, p); + return temp; +} + + + +void *qmalloc (int size) +{ + void *b; + b = malloc(size); + memset (b, 0, size); + return b; +} + +char *copystring (char *s) +{ + char *b; + b = malloc(strlen(s)+1); + strcpy (b,s); + return b; +} + +/* +=============== +QE_CheckAutoSave + +If five minutes have passed since making a change +and the map hasn't been saved, save it out. +=============== +*/ +void QE_CheckAutoSave( void ) +{ + static clock_t s_start; + clock_t now; + + now = clock(); + + if ( modified != 1 || !s_start) + { + s_start = now; + return; + } + + if ( now - s_start > ( CLOCKS_PER_SEC * 60 * QE_AUTOSAVE_INTERVAL ) ) + { + Sys_Printf ("Autosaving...\n"); + Sys_Status ("Autosaving...", 0 ); + + Map_SaveFile (ValueForKey(g_qeglobals.d_project_entity, "autosave"), false); + + Sys_Status ("Autosaving...Saved.", 0 ); + modified = 2; + s_start = now; + } +} + + + +/* +=========== +QE_LoadProject +=========== +*/ +qboolean QE_LoadProject (char *projectfile) +{ + char *data; + + Sys_Printf ("QE_LoadProject (%s)\n", projectfile); + + if ( LoadFileNoCrash (projectfile, (void *)&data) == -1) + return false; + StartTokenParsing (data); + g_qeglobals.d_project_entity = Entity_Parse (true); + if (!g_qeglobals.d_project_entity) + Error ("Couldn't parse %s", projectfile); + free (data); + + Eclass_InitForSourceDirectory (ValueForKey (g_qeglobals.d_project_entity, "entitypath")); + + FillClassList (); // list in entity window + + Map_New (); + + FillTextureMenu (); + FillBSPMenu (); + + return true; +} + +/* +=========== +QE_KeyDown +=========== +*/ +#define SPEED_MOVE 32 +#define SPEED_TURN 22.5 + +qboolean QE_KeyDown (int key) +{ + switch (key) + { + case 'K': + PostMessage( g_qeglobals.d_hwndMain, WM_COMMAND, ID_MISC_SELECTENTITYCOLOR, 0 ); + break; + + case VK_UP: + VectorMA (camera.origin, SPEED_MOVE, camera.forward, camera.origin); + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case VK_DOWN: + VectorMA (camera.origin, -SPEED_MOVE, camera.forward, camera.origin); + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case VK_LEFT: + camera.angles[1] += SPEED_TURN; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case VK_RIGHT: + camera.angles[1] -= SPEED_TURN; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case 'D': + camera.origin[2] += SPEED_MOVE; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY|W_Z_OVERLAY); + break; + case 'C': + camera.origin[2] -= SPEED_MOVE; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY|W_Z_OVERLAY); + break; + case 'A': + camera.angles[0] += SPEED_TURN; + if (camera.angles[0] > 85) + camera.angles[0] = 85; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case 'Z': + camera.angles[0] -= SPEED_TURN; + if (camera.angles[0] < -85) + camera.angles[0] = -85; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case VK_COMMA: + VectorMA (camera.origin, -SPEED_MOVE, camera.right, camera.origin); + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + case VK_PERIOD: + VectorMA (camera.origin, SPEED_MOVE, camera.right, camera.origin); + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + + case '0': + g_qeglobals.d_showgrid = !g_qeglobals.d_showgrid; + PostMessage( g_qeglobals.d_hwndXY, WM_PAINT, 0, 0 ); + break; + case '1': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_1, 0); + break; + case '2': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_2, 0); + break; + case '3': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_4, 0); + break; + case '4': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_8, 0); + break; + case '5': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_16, 0); + break; + case '6': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_32, 0); + break; + case '7': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_GRID_64, 0); + break; + + case 'E': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_SELECTION_DRAGEDGES, 0); + break; + case 'V': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_SELECTION_DRAGVERTECIES, 0); + break; + + case 'N': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_ENTITY, 0); + break; + case 'O': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_CONSOLE, 0); + break; + case 'T': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_TEXTURE, 0); + break; + case 'S': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_TEXTURES_INSPECTOR, 0); + break; + + case ' ': + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_SELECTION_CLONE, 0); + break; + + case VK_BACK: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_SELECTION_DELETE, 0); + break; + case VK_ESCAPE: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_SELECTION_DESELECT, 0); + break; + case VK_END: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_CENTER, 0); + break; + + case VK_DELETE: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_ZOOMIN, 0); + break; + case VK_INSERT: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_ZOOMOUT, 0); + break; + + case VK_NEXT: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_DOWNFLOOR, 0); + break; + case VK_PRIOR: + PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_UPFLOOR, 0); + break; + + default: + return false; + + } + + return true; +} + +/* +=============== +ConnectEntities + +Sets target / targetname on the two entities selected +from the first selected to the secon +=============== +*/ +void ConnectEntities (void) +{ + entity_t *e1, *e2, *e; + char *target, *tn; + int maxtarg, targetnum; + char newtarg[32]; + + if (g_qeglobals.d_select_count != 2) + { + Sys_Status ("Must have two brushes selected.", 0); + Sys_Beep (); + return; + } + + e1 = g_qeglobals.d_select_order[0]->owner; + e2 = g_qeglobals.d_select_order[1]->owner; + + if (e1 == world_entity || e2 == world_entity) + { + Sys_Status ("Can't connect to the world.", 0); + Sys_Beep (); + return; + } + + if (e1 == e2) + { + Sys_Status ("Brushes are from same entity.", 0); + Sys_Beep (); + return; + } + + target = ValueForKey (e1, "target"); + if (target && target[0]) + strcpy (newtarg, target); + else + { + target = ValueForKey (e2, "targetname"); + if (target && target[0]) + strcpy (newtarg, target); + else + { + // make a unique target value + maxtarg = 0; + for (e=entities.next ; e != &entities ; e=e->next) + { + tn = ValueForKey (e, "targetname"); + if (tn && tn[0]) + { + targetnum = atoi(tn+1); + if (targetnum > maxtarg) + maxtarg = targetnum; + } + } + sprintf (newtarg, "t%i", maxtarg+1); + } + } + + SetKeyValue (e1, "target", newtarg); + SetKeyValue (e2, "targetname", newtarg); + Sys_UpdateWindows (W_XY | W_CAMERA); + + Select_Deselect(); + Select_Brush (g_qeglobals.d_select_order[1]); +} + +qboolean QE_SingleBrush (void) +{ + if ( (selected_brushes.next == &selected_brushes) + || (selected_brushes.next->next != &selected_brushes) ) + { + Sys_Printf ("Error: you must have a single brush selected\n"); + return false; + } + if (selected_brushes.next->owner->eclass->fixedsize) + { + Sys_Printf ("Error: you cannot manipulate fixed size entities\n"); + return false; + } + + return true; +} + +void QE_Init (void) +{ + /* + ** initialize variables + */ + g_qeglobals.d_gridsize = 8; + g_qeglobals.d_showgrid = true; + + /* + ** other stuff + */ + Texture_Init (); + Cam_Init (); + XY_Init (); + Z_Init (); +} + +void QE_ConvertDOSToUnixName( char *dst, const char *src ) +{ + while ( *src ) + { + if ( *src == '\\' ) + *dst = '/'; + else + *dst = *src; + dst++; src++; + } + *dst = 0; +} + +int g_numbrushes, g_numentities; + +void QE_CountBrushesAndUpdateStatusBar( void ) +{ + static int s_lastbrushcount, s_lastentitycount; + static qboolean s_didonce; + + entity_t *e; + brush_t *b, *next; + + g_numbrushes = 0; + g_numentities = 0; + + if ( active_brushes.next != NULL ) + { + for ( b = active_brushes.next ; b != NULL && b != &active_brushes ; b=next) + { + next = b->next; + if (b->brush_faces ) + { + if ( !b->owner->eclass->fixedsize) + g_numbrushes++; + else + g_numentities++; + } + } + } + + if ( entities.next != NULL ) + { + for ( e = entities.next ; e != &entities && g_numentities != MAX_MAP_ENTITIES ; e = e->next) + { + g_numentities++; + } + } + + if ( ( ( g_numbrushes != s_lastbrushcount ) || ( g_numentities != s_lastentitycount ) ) || ( !s_didonce ) ) + { + Sys_UpdateStatusBar(); + + s_lastbrushcount = g_numbrushes; + s_lastentitycount = g_numentities; + s_didonce = true; + } +} + diff --git a/tools/quake2/extra/qe4/qe3.h b/tools/quake2/extra/qe4/qe3.h new file mode 100644 index 00000000..67930599 --- /dev/null +++ b/tools/quake2/extra/qe4/qe3.h @@ -0,0 +1,306 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#ifndef __QE3_H__ +#define __QE3_H__ + +// disable data conversion warnings for gl +#pragma warning(disable : 4244) // MIPS +#pragma warning(disable : 4136) // X86 +#pragma warning(disable : 4051) // ALPHA + +#include + +#include +#include +#include +#include "glingr.h" +#include +#include + +#include "cmdlib.h" +#include "mathlib.h" +#include "parse.h" +#include "lbmlib.h" + +#include +#include "afxres.h" +#include "resource.h" + +#include "qedefs.h" + +typedef struct +{ + vec3_t normal; + double dist; + int type; +} plane_t; + +#include "qfiles.h" + +#include "textures.h" +#include "brush.h" +#include "entity.h" +#include "map.h" +#include "select.h" + +#include "camera.h" +#include "xy.h" +#include "z.h" +#include "mru.h" + +typedef struct +{ + int p1, p2; + face_t *f1, *f2; +} pedge_t; + +typedef struct +{ + int iSize; + int iTexMenu; // nearest, linear, etc + float fGamma; // gamma for textures + char szProject[256]; // last project loaded + vec3_t colors[COLOR_LAST]; + qboolean show_names, + show_coordinates; + int exclude; +} SavedInfo_t; + +// +// system functions +// +void Sys_UpdateStatusBar( void ); +void Sys_UpdateWindows (int bits); +void Sys_Beep (void); +void Sys_ClearPrintf (void); +void Sys_Printf (char *text, ...); +double Sys_DoubleTime (void); +void Sys_GetCursorPos (int *x, int *y); +void Sys_SetCursorPos (int x, int y); +void Sys_SetTitle (char *text); +void Sys_BeginWait (void); +void Sys_EndWait (void); +void Sys_Status(const char *psz, int part); + +/* +** most of the QE globals are stored in this structure +*/ +typedef struct +{ + qboolean d_showgrid; + int d_gridsize; + + int d_num_entities; + + entity_t *d_project_entity; + + float d_new_brush_bottom_z, + d_new_brush_top_z; + + HINSTANCE d_hInstance; + + HGLRC d_hglrcBase; + HDC d_hdcBase; + + HWND d_hwndMain; + HWND d_hwndCamera; + HWND d_hwndEdit; + HWND d_hwndEntity; + HWND d_hwndTexture; + HWND d_hwndXY; + HWND d_hwndZ; + HWND d_hwndStatus; + + vec3_t d_points[MAX_POINTS]; + int d_numpoints; + pedge_t d_edges[MAX_EDGES]; + int d_numedges; + + int d_num_move_points; + float *d_move_points[1024]; + + qtexture_t *d_qtextures; + + texturewin_t d_texturewin; + + int d_pointfile_display_list; + + xy_t d_xy; + + LPMRUMENU d_lpMruMenu; + + SavedInfo_t d_savedinfo; + + int d_workcount; + + // connect entities uses the last two brushes selected + int d_select_count; + brush_t *d_select_order[2]; + vec3_t d_select_translate; // for dragging w/o making new display lists + select_t d_select_mode; + + int d_font_list; + + int d_parsed_brushes; + + qboolean show_blocks; +} QEGlobals_t; + +void *qmalloc (int size); +char *copystring (char *s); +char *ExpandReletivePath (char *p); + +void Pointfile_Delete (void); +void Pointfile_Check (void); +void Pointfile_Next (void); +void Pointfile_Prev (void); +void Pointfile_Clear (void); +void Pointfile_Draw( void ); +void Pointfile_Load( void ); + +// +// drag.c +// +void Drag_Begin (int x, int y, int buttons, + vec3_t xaxis, vec3_t yaxis, + vec3_t origin, vec3_t dir); +void Drag_MouseMoved (int x, int y, int buttons); +void Drag_MouseUp (void); + +// +// csg.c +// +void CSG_MakeHollow (void); +void CSG_Subtract (void); + +// +// vertsel.c +// + +void SetupVertexSelection (void); +void SelectEdgeByRay (vec3_t org, vec3_t dir); +void SelectVertexByRay (vec3_t org, vec3_t dir); + +void ConnectEntities (void); + +extern int update_bits; + +extern int screen_width; +extern int screen_height; + +extern HANDLE bsp_process; + +char *TranslateString (char *buf); + +void ProjectDialog (void); + +void FillTextureMenu (void); +void FillBSPMenu (void); + +BOOL CALLBACK Win_Dialog ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter +); + + +// +// win_cam.c +// +void WCam_Create (HINSTANCE hInstance); + + +// +// win_xy.c +// +void WXY_Create (HINSTANCE hInstance); + +// +// win_z.c +// +void WZ_Create (HINSTANCE hInstance); + +// +// win_ent.c +// + + +// +// win_main.c +// +void Main_Create (HINSTANCE hInstance); +extern BOOL SaveWindowState(HWND hWnd, const char *pszName); +extern BOOL LoadWindowState(HWND hWnd, const char *pszName); + +extern BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize); +extern BOOL loadRegistryInfo(const char *pszName, void *pvBuf, long *plSize); + +// +// entityw.c +// +BOOL CreateEntityWindow(HINSTANCE hInstance); +void FillClassList (void); +BOOL UpdateEntitySel(eclass_t *pec); +void SetInspectorMode(int iType); +int DrawTexControls(HWND hWnd); +void SetSpawnFlags(void); +void GetSpawnFlags(void); +void SetKeyValuePairs(void); +extern void BuildGammaTable(float g); + + +// win_dlg.c + +void DoGamma(void); +void DoFind(void); +void DoRotate(void); +void DoSides(void); +void DoAbout(void); +void DoSurface(void); + +/* +** QE function declarations +*/ +void QE_CheckAutoSave( void ); +void QE_ConvertDOSToUnixName( char *dst, const char *src ); +void QE_CountBrushesAndUpdateStatusBar( void ); +void QE_CheckOpenGLForErrors(void); +void QE_ExpandBspString (char *bspaction, char *out, char *mapname); +void QE_Init (void); +qboolean QE_KeyDown (int key); +qboolean QE_LoadProject (char *projectfile); +qboolean QE_SingleBrush (void); + +/* +** QE Win32 function declarations +*/ +int QEW_SetupPixelFormat(HDC hDC, qboolean zbuffer ); +void QEW_StopGL( HWND hWnd, HGLRC hGLRC, HDC hDC ); + +/* +** extern declarations +*/ +extern QEGlobals_t g_qeglobals; + +#endif diff --git a/tools/quake2/extra/qe4/qe4.mak b/tools/quake2/extra/qe4/qe4.mak new file mode 100644 index 00000000..9032cfa4 --- /dev/null +++ b/tools/quake2/extra/qe4/qe4.mak @@ -0,0 +1,3716 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 +# TARGTYPE "Win32 (ALPHA) Application" 0x0601 + +!IF "$(CFG)" == "" +CFG=qe3 - Win32 (ALPHA) Debug +!MESSAGE No configuration specified. Defaulting to qe3 - Win32 (ALPHA) Debug. +!ENDIF + +!IF "$(CFG)" != "qe3 - Win32 Release" && "$(CFG)" != "qe3 - Win32 Debug" &&\ + "$(CFG)" != "qe3 - Win32 (ALPHA) Debug" && "$(CFG)" !=\ + "qe3 - Win32 (ALPHA) Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "qe4.mak" CFG="qe3 - Win32 (ALPHA) Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "qe3 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "qe3 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "qe3 - Win32 (ALPHA) Debug" (based on "Win32 (ALPHA) Application") +!MESSAGE "qe3 - Win32 (ALPHA) Release" (based on "Win32 (ALPHA) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "qe3 - Win32 Debug" + +!IF "$(CFG)" == "qe3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\qe4.exe" "$(OUTDIR)\qe4.bsc" + +CLEAN : + -@erase "$(INTDIR)\brush.obj" + -@erase "$(INTDIR)\brush.sbr" + -@erase "$(INTDIR)\camera.obj" + -@erase "$(INTDIR)\camera.sbr" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\cmdlib.sbr" + -@erase "$(INTDIR)\csg.obj" + -@erase "$(INTDIR)\csg.sbr" + -@erase "$(INTDIR)\drag.obj" + -@erase "$(INTDIR)\drag.sbr" + -@erase "$(INTDIR)\eclass.obj" + -@erase "$(INTDIR)\eclass.sbr" + -@erase "$(INTDIR)\entity.obj" + -@erase "$(INTDIR)\entity.sbr" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\lbmlib.sbr" + -@erase "$(INTDIR)\map.obj" + -@erase "$(INTDIR)\map.sbr" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\mathlib.sbr" + -@erase "$(INTDIR)\mru.obj" + -@erase "$(INTDIR)\mru.sbr" + -@erase "$(INTDIR)\parse.obj" + -@erase "$(INTDIR)\parse.sbr" + -@erase "$(INTDIR)\points.obj" + -@erase "$(INTDIR)\points.sbr" + -@erase "$(INTDIR)\qe3.obj" + -@erase "$(INTDIR)\qe3.sbr" + -@erase "$(INTDIR)\select.obj" + -@erase "$(INTDIR)\select.sbr" + -@erase "$(INTDIR)\textures.obj" + -@erase "$(INTDIR)\textures.sbr" + -@erase "$(INTDIR)\vertsel.obj" + -@erase "$(INTDIR)\vertsel.sbr" + -@erase "$(INTDIR)\win_cam.obj" + -@erase "$(INTDIR)\win_cam.sbr" + -@erase "$(INTDIR)\win_dlg.obj" + -@erase "$(INTDIR)\win_dlg.sbr" + -@erase "$(INTDIR)\win_ent.obj" + -@erase "$(INTDIR)\win_ent.sbr" + -@erase "$(INTDIR)\win_main.obj" + -@erase "$(INTDIR)\win_main.sbr" + -@erase "$(INTDIR)\win_qe3.obj" + -@erase "$(INTDIR)\win_qe3.res" + -@erase "$(INTDIR)\win_qe3.sbr" + -@erase "$(INTDIR)\win_xy.obj" + -@erase "$(INTDIR)\win_xy.sbr" + -@erase "$(INTDIR)\win_z.obj" + -@erase "$(INTDIR)\win_z.sbr" + -@erase "$(INTDIR)\xy.obj" + -@erase "$(INTDIR)\xy.sbr" + -@erase "$(INTDIR)\z.obj" + -@erase "$(INTDIR)\z.sbr" + -@erase "$(OUTDIR)\qe4.bsc" + -@erase "$(OUTDIR)\qe4.exe" + -@erase "$(OUTDIR)\qe4.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /GX /Zd /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fr /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /Zd /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fr"$(INTDIR)/" /Fp"$(INTDIR)/qe4.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\Release/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/win_qe3.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qe4.bsc" +BSC32_SBRS= \ + "$(INTDIR)\brush.sbr" \ + "$(INTDIR)\camera.sbr" \ + "$(INTDIR)\cmdlib.sbr" \ + "$(INTDIR)\csg.sbr" \ + "$(INTDIR)\drag.sbr" \ + "$(INTDIR)\eclass.sbr" \ + "$(INTDIR)\entity.sbr" \ + "$(INTDIR)\lbmlib.sbr" \ + "$(INTDIR)\map.sbr" \ + "$(INTDIR)\mathlib.sbr" \ + "$(INTDIR)\mru.sbr" \ + "$(INTDIR)\parse.sbr" \ + "$(INTDIR)\points.sbr" \ + "$(INTDIR)\qe3.sbr" \ + "$(INTDIR)\select.sbr" \ + "$(INTDIR)\textures.sbr" \ + "$(INTDIR)\vertsel.sbr" \ + "$(INTDIR)\win_cam.sbr" \ + "$(INTDIR)\win_dlg.sbr" \ + "$(INTDIR)\win_ent.sbr" \ + "$(INTDIR)\win_main.sbr" \ + "$(INTDIR)\win_qe3.sbr" \ + "$(INTDIR)\win_xy.sbr" \ + "$(INTDIR)\win_z.sbr" \ + "$(INTDIR)\xy.sbr" \ + "$(INTDIR)\z.sbr" + +"$(OUTDIR)\qe4.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +LINK32_FLAGS=comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib\ + gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib\ + oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/qe4.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/qe4.exe" +LINK32_OBJS= \ + "$(INTDIR)\brush.obj" \ + "$(INTDIR)\camera.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\csg.obj" \ + "$(INTDIR)\drag.obj" \ + "$(INTDIR)\eclass.obj" \ + "$(INTDIR)\entity.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\mru.obj" \ + "$(INTDIR)\parse.obj" \ + "$(INTDIR)\points.obj" \ + "$(INTDIR)\qe3.obj" \ + "$(INTDIR)\select.obj" \ + "$(INTDIR)\textures.obj" \ + "$(INTDIR)\vertsel.obj" \ + "$(INTDIR)\win_cam.obj" \ + "$(INTDIR)\win_dlg.obj" \ + "$(INTDIR)\win_ent.obj" \ + "$(INTDIR)\win_main.obj" \ + "$(INTDIR)\win_qe3.obj" \ + "$(INTDIR)\win_qe3.res" \ + "$(INTDIR)\win_xy.obj" \ + "$(INTDIR)\win_z.obj" \ + "$(INTDIR)\xy.obj" \ + "$(INTDIR)\z.obj" + +"$(OUTDIR)\qe4.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\qe4.exe" "$(OUTDIR)\qe4.bsc" + +CLEAN : + -@erase "$(INTDIR)\brush.obj" + -@erase "$(INTDIR)\brush.sbr" + -@erase "$(INTDIR)\camera.obj" + -@erase "$(INTDIR)\camera.sbr" + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\cmdlib.sbr" + -@erase "$(INTDIR)\csg.obj" + -@erase "$(INTDIR)\csg.sbr" + -@erase "$(INTDIR)\drag.obj" + -@erase "$(INTDIR)\drag.sbr" + -@erase "$(INTDIR)\eclass.obj" + -@erase "$(INTDIR)\eclass.sbr" + -@erase "$(INTDIR)\entity.obj" + -@erase "$(INTDIR)\entity.sbr" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\lbmlib.sbr" + -@erase "$(INTDIR)\map.obj" + -@erase "$(INTDIR)\map.sbr" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\mathlib.sbr" + -@erase "$(INTDIR)\mru.obj" + -@erase "$(INTDIR)\mru.sbr" + -@erase "$(INTDIR)\parse.obj" + -@erase "$(INTDIR)\parse.sbr" + -@erase "$(INTDIR)\points.obj" + -@erase "$(INTDIR)\points.sbr" + -@erase "$(INTDIR)\qe3.obj" + -@erase "$(INTDIR)\qe3.sbr" + -@erase "$(INTDIR)\select.obj" + -@erase "$(INTDIR)\select.sbr" + -@erase "$(INTDIR)\textures.obj" + -@erase "$(INTDIR)\textures.sbr" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\vertsel.obj" + -@erase "$(INTDIR)\vertsel.sbr" + -@erase "$(INTDIR)\win_cam.obj" + -@erase "$(INTDIR)\win_cam.sbr" + -@erase "$(INTDIR)\win_dlg.obj" + -@erase "$(INTDIR)\win_dlg.sbr" + -@erase "$(INTDIR)\win_ent.obj" + -@erase "$(INTDIR)\win_ent.sbr" + -@erase "$(INTDIR)\win_main.obj" + -@erase "$(INTDIR)\win_main.sbr" + -@erase "$(INTDIR)\win_qe3.obj" + -@erase "$(INTDIR)\win_qe3.res" + -@erase "$(INTDIR)\win_qe3.sbr" + -@erase "$(INTDIR)\win_xy.obj" + -@erase "$(INTDIR)\win_xy.sbr" + -@erase "$(INTDIR)\win_z.obj" + -@erase "$(INTDIR)\win_z.sbr" + -@erase "$(INTDIR)\xy.obj" + -@erase "$(INTDIR)\xy.sbr" + -@erase "$(INTDIR)\z.obj" + -@erase "$(INTDIR)\z.sbr" + -@erase "$(OUTDIR)\qe4.bsc" + -@erase "$(OUTDIR)\qe4.exe" + -@erase "$(OUTDIR)\qe4.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /FR"$(INTDIR)/" /Fp"$(INTDIR)/qe4.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\Debug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/win_qe3.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qe4.bsc" +BSC32_SBRS= \ + "$(INTDIR)\brush.sbr" \ + "$(INTDIR)\camera.sbr" \ + "$(INTDIR)\cmdlib.sbr" \ + "$(INTDIR)\csg.sbr" \ + "$(INTDIR)\drag.sbr" \ + "$(INTDIR)\eclass.sbr" \ + "$(INTDIR)\entity.sbr" \ + "$(INTDIR)\lbmlib.sbr" \ + "$(INTDIR)\map.sbr" \ + "$(INTDIR)\mathlib.sbr" \ + "$(INTDIR)\mru.sbr" \ + "$(INTDIR)\parse.sbr" \ + "$(INTDIR)\points.sbr" \ + "$(INTDIR)\qe3.sbr" \ + "$(INTDIR)\select.sbr" \ + "$(INTDIR)\textures.sbr" \ + "$(INTDIR)\vertsel.sbr" \ + "$(INTDIR)\win_cam.sbr" \ + "$(INTDIR)\win_dlg.sbr" \ + "$(INTDIR)\win_ent.sbr" \ + "$(INTDIR)\win_main.sbr" \ + "$(INTDIR)\win_qe3.sbr" \ + "$(INTDIR)\win_xy.sbr" \ + "$(INTDIR)\win_z.sbr" \ + "$(INTDIR)\xy.sbr" \ + "$(INTDIR)\z.sbr" + +"$(OUTDIR)\qe4.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /map /debug /machine:I386 +LINK32_FLAGS=comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib\ + gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib\ + oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows\ + /profile /map:"$(INTDIR)/qe4.map" /debug /machine:I386 /out:"$(OUTDIR)/qe4.exe"\ + +LINK32_OBJS= \ + "$(INTDIR)\brush.obj" \ + "$(INTDIR)\camera.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\csg.obj" \ + "$(INTDIR)\drag.obj" \ + "$(INTDIR)\eclass.obj" \ + "$(INTDIR)\entity.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\mru.obj" \ + "$(INTDIR)\parse.obj" \ + "$(INTDIR)\points.obj" \ + "$(INTDIR)\qe3.obj" \ + "$(INTDIR)\select.obj" \ + "$(INTDIR)\textures.obj" \ + "$(INTDIR)\vertsel.obj" \ + "$(INTDIR)\win_cam.obj" \ + "$(INTDIR)\win_dlg.obj" \ + "$(INTDIR)\win_ent.obj" \ + "$(INTDIR)\win_main.obj" \ + "$(INTDIR)\win_qe3.obj" \ + "$(INTDIR)\win_qe3.res" \ + "$(INTDIR)\win_xy.obj" \ + "$(INTDIR)\win_z.obj" \ + "$(INTDIR)\xy.obj" \ + "$(INTDIR)\z.obj" + +"$(OUTDIR)\qe4.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "qe3___Wi" +# PROP BASE Intermediate_Dir "qe3___Wi" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "debug_alpha" +# PROP Intermediate_Dir "debug_alpha" +# PROP Target_Dir "" +OUTDIR=.\debug_alpha +INTDIR=.\debug_alpha + +ALL : "$(OUTDIR)\qe3.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /Gt0 /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /Gt0 /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MLd /Gt0 /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qe3.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\debug_alpha/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /alpha +# ADD MTL /nologo /D "_DEBUG" /alpha +MTL_PROJ=/nologo /D "_DEBUG" /alpha +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/win_qe3.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qe3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:ALPHA +# SUBTRACT BASE LINK32 /incremental:no +# ADD LINK32 comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:ALPHA +# SUBTRACT LINK32 /incremental:no +LINK32_FLAGS=comctl32.lib opengl32.lib glu32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo\ + /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)/qe3.pdb" /debug\ + /machine:ALPHA /out:"$(OUTDIR)/qe3.exe" +LINK32_OBJS= \ + "$(INTDIR)\brush.obj" \ + "$(INTDIR)\camera.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\csg.obj" \ + "$(INTDIR)\drag.obj" \ + "$(INTDIR)\eclass.obj" \ + "$(INTDIR)\entity.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\mru.obj" \ + "$(INTDIR)\parse.obj" \ + "$(INTDIR)\points.obj" \ + "$(INTDIR)\qe3.obj" \ + "$(INTDIR)\select.obj" \ + "$(INTDIR)\textures.obj" \ + "$(INTDIR)\vertsel.obj" \ + "$(INTDIR)\win_cam.obj" \ + "$(INTDIR)\win_dlg.obj" \ + "$(INTDIR)\win_ent.obj" \ + "$(INTDIR)\win_main.obj" \ + "$(INTDIR)\win_qe3.obj" \ + "$(INTDIR)\win_qe3.res" \ + "$(INTDIR)\win_xy.obj" \ + "$(INTDIR)\win_z.obj" \ + "$(INTDIR)\xy.obj" \ + "$(INTDIR)\z.obj" + +"$(OUTDIR)\qe3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "qe3___W0" +# PROP BASE Intermediate_Dir "qe3___W0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "release_alpha" +# PROP Intermediate_Dir "release_alpha" +# PROP Target_Dir "" +OUTDIR=.\release_alpha +INTDIR=.\release_alpha + +ALL : "$(OUTDIR)\qe3.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /ML /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/qe3.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\release_alpha/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /alpha +# ADD MTL /nologo /D "NDEBUG" /alpha +MTL_PROJ=/nologo /D "NDEBUG" /alpha +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/win_qe3.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/qe3.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:ALPHA +# ADD LINK32 comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:ALPHA +LINK32_FLAGS=comctl32.lib opengl32.lib glu32.lib kernel32.lib user32.lib\ + gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib\ + oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/qe3.pdb" /machine:ALPHA\ + /out:"$(OUTDIR)/qe3.exe" +LINK32_OBJS= \ + "$(INTDIR)\brush.obj" \ + "$(INTDIR)\camera.obj" \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\csg.obj" \ + "$(INTDIR)\drag.obj" \ + "$(INTDIR)\eclass.obj" \ + "$(INTDIR)\entity.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\mru.obj" \ + "$(INTDIR)\parse.obj" \ + "$(INTDIR)\points.obj" \ + "$(INTDIR)\qe3.obj" \ + "$(INTDIR)\select.obj" \ + "$(INTDIR)\textures.obj" \ + "$(INTDIR)\vertsel.obj" \ + "$(INTDIR)\win_cam.obj" \ + "$(INTDIR)\win_dlg.obj" \ + "$(INTDIR)\win_ent.obj" \ + "$(INTDIR)\win_main.obj" \ + "$(INTDIR)\win_qe3.obj" \ + "$(INTDIR)\win_qe3.res" \ + "$(INTDIR)\win_xy.obj" \ + "$(INTDIR)\win_z.obj" \ + "$(INTDIR)\xy.obj" \ + "$(INTDIR)\z.obj" + +"$(OUTDIR)\qe3.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +################################################################################ +# Begin Target + +# Name "qe3 - Win32 Release" +# Name "qe3 - Win32 Debug" +# Name "qe3 - Win32 (ALPHA) Debug" +# Name "qe3 - Win32 (ALPHA) Release" + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\textures.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\textures.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_TEXTU=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\textures.obj" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + +"$(INTDIR)\textures.sbr" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_TEXTU=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\textures.obj" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + +"$(INTDIR)\textures.sbr" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_TEXTU=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\textures.obj" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_TEXTU=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\textures.obj" : $(SOURCE) $(DEP_CPP_TEXTU) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\resource.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mathlib.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mathlib.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_MATHL=\ + ".\cmdlib.h"\ + ".\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + +"$(INTDIR)\mathlib.sbr" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_MATHL=\ + ".\cmdlib.h"\ + ".\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + +"$(INTDIR)\mathlib.sbr" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_MATHL=\ + ".\cmdlib.h"\ + ".\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_MATHL=\ + ".\cmdlib.h"\ + ".\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\map.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\map.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_MAP_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\map.obj" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + +"$(INTDIR)\map.sbr" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_MAP_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\map.obj" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + +"$(INTDIR)\map.sbr" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_MAP_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\map.obj" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_MAP_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\map.obj" : $(SOURCE) $(DEP_CPP_MAP_C) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cmdlib.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\cmdlib.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_CMDLI=\ + ".\cmdlib.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + +"$(INTDIR)\cmdlib.sbr" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_CMDLI=\ + ".\cmdlib.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + +"$(INTDIR)\cmdlib.sbr" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_CMDLI=\ + ".\cmdlib.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_CMDLI=\ + ".\cmdlib.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\brush.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\brush.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_BRUSH=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\brush.obj" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + +"$(INTDIR)\brush.sbr" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_BRUSH=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\brush.obj" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + +"$(INTDIR)\brush.sbr" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_BRUSH=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\brush.obj" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_BRUSH=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\brush.obj" : $(SOURCE) $(DEP_CPP_BRUSH) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\notes.txt + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_cam.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_cam.obj" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + +"$(INTDIR)\win_cam.sbr" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_cam.obj" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + +"$(INTDIR)\win_cam.sbr" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_cam.obj" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_cam.obj" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qe3.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\parse.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\parse.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_PARSE=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\parse.obj" : $(SOURCE) $(DEP_CPP_PARSE) "$(INTDIR)" + +"$(INTDIR)\parse.sbr" : $(SOURCE) $(DEP_CPP_PARSE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_PARSE=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\parse.obj" : $(SOURCE) $(DEP_CPP_PARSE) "$(INTDIR)" + +"$(INTDIR)\parse.sbr" : $(SOURCE) $(DEP_CPP_PARSE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_PARSE=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\parse.obj" : $(SOURCE) $(DEP_CPP_PARSE) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_PARSE=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\parse.obj" : $(SOURCE) $(DEP_CPP_PARSE) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\camera.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\camera.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_CAMER=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\camera.obj" : $(SOURCE) $(DEP_CPP_CAMER) "$(INTDIR)" + +"$(INTDIR)\camera.sbr" : $(SOURCE) $(DEP_CPP_CAMER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_CAMER=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\camera.obj" : $(SOURCE) $(DEP_CPP_CAMER) "$(INTDIR)" + +"$(INTDIR)\camera.sbr" : $(SOURCE) $(DEP_CPP_CAMER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_CAMER=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\camera.obj" : $(SOURCE) $(DEP_CPP_CAMER) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_CAMER=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\camera.obj" : $(SOURCE) $(DEP_CPP_CAMER) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_qe3.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_xy.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_X=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_xy.obj" : $(SOURCE) $(DEP_CPP_WIN_X) "$(INTDIR)" + +"$(INTDIR)\win_xy.sbr" : $(SOURCE) $(DEP_CPP_WIN_X) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_X=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_xy.obj" : $(SOURCE) $(DEP_CPP_WIN_X) "$(INTDIR)" + +"$(INTDIR)\win_xy.sbr" : $(SOURCE) $(DEP_CPP_WIN_X) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_X=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_xy.obj" : $(SOURCE) $(DEP_CPP_WIN_X) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_X=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_xy.obj" : $(SOURCE) $(DEP_CPP_WIN_X) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_qe3.rc + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_RSC_WIN_Q=\ + ".\icon1.ico"\ + ".\q.bmp"\ + ".\toolbar1.bmp"\ + + +"$(INTDIR)\win_qe3.res" : $(SOURCE) $(DEP_RSC_WIN_Q) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_RSC_WIN_Q=\ + ".\icon1.ico"\ + ".\q.bmp"\ + ".\toolbar1.bmp"\ + + +"$(INTDIR)\win_qe3.res" : $(SOURCE) $(DEP_RSC_WIN_Q) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_RSC_WIN_Q=\ + ".\icon1.ico"\ + ".\toolbar1.bmp"\ + + +"$(INTDIR)\win_qe3.res" : $(SOURCE) $(DEP_RSC_WIN_Q) "$(INTDIR)" + $(RSC) /l 0x409 /fo"$(INTDIR)/win_qe3.res" /d "_DEBUG" $(SOURCE) + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_RSC_WIN_Q=\ + ".\icon1.ico"\ + ".\toolbar1.bmp"\ + + +"$(INTDIR)\win_qe3.res" : $(SOURCE) $(DEP_RSC_WIN_Q) "$(INTDIR)" + $(RSC) /l 0x409 /fo"$(INTDIR)/win_qe3.res" /d "NDEBUG" $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\xy.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_XY_C14=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\xy.obj" : $(SOURCE) $(DEP_CPP_XY_C14) "$(INTDIR)" + +"$(INTDIR)\xy.sbr" : $(SOURCE) $(DEP_CPP_XY_C14) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_XY_C14=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\xy.obj" : $(SOURCE) $(DEP_CPP_XY_C14) "$(INTDIR)" + +"$(INTDIR)\xy.sbr" : $(SOURCE) $(DEP_CPP_XY_C14) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_XY_C14=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\xy.obj" : $(SOURCE) $(DEP_CPP_XY_C14) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_XY_C14=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\xy.obj" : $(SOURCE) $(DEP_CPP_XY_C14) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\xy.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\select.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_SELEC=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\select.obj" : $(SOURCE) $(DEP_CPP_SELEC) "$(INTDIR)" + +"$(INTDIR)\select.sbr" : $(SOURCE) $(DEP_CPP_SELEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_SELEC=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\select.obj" : $(SOURCE) $(DEP_CPP_SELEC) "$(INTDIR)" + +"$(INTDIR)\select.sbr" : $(SOURCE) $(DEP_CPP_SELEC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_SELEC=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\select.obj" : $(SOURCE) $(DEP_CPP_SELEC) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_SELEC=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\select.obj" : $(SOURCE) $(DEP_CPP_SELEC) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_qe3.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_QE=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_qe3.obj" : $(SOURCE) $(DEP_CPP_WIN_QE) "$(INTDIR)" + +"$(INTDIR)\win_qe3.sbr" : $(SOURCE) $(DEP_CPP_WIN_QE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_QE=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_qe3.obj" : $(SOURCE) $(DEP_CPP_WIN_QE) "$(INTDIR)" + +"$(INTDIR)\win_qe3.sbr" : $(SOURCE) $(DEP_CPP_WIN_QE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_QE=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_qe3.obj" : $(SOURCE) $(DEP_CPP_WIN_QE) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_QE=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_qe3.obj" : $(SOURCE) $(DEP_CPP_WIN_QE) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\select.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qe3.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_QE3_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\qe3.obj" : $(SOURCE) $(DEP_CPP_QE3_C) "$(INTDIR)" + +"$(INTDIR)\qe3.sbr" : $(SOURCE) $(DEP_CPP_QE3_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_QE3_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\qe3.obj" : $(SOURCE) $(DEP_CPP_QE3_C) "$(INTDIR)" + +"$(INTDIR)\qe3.sbr" : $(SOURCE) $(DEP_CPP_QE3_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_QE3_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\qe3.obj" : $(SOURCE) $(DEP_CPP_QE3_C) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_QE3_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\qe3.obj" : $(SOURCE) $(DEP_CPP_QE3_C) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\eclass.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_ECLAS=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\eclass.obj" : $(SOURCE) $(DEP_CPP_ECLAS) "$(INTDIR)" + +"$(INTDIR)\eclass.sbr" : $(SOURCE) $(DEP_CPP_ECLAS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_ECLAS=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\eclass.obj" : $(SOURCE) $(DEP_CPP_ECLAS) "$(INTDIR)" + +"$(INTDIR)\eclass.sbr" : $(SOURCE) $(DEP_CPP_ECLAS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_ECLAS=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\eclass.obj" : $(SOURCE) $(DEP_CPP_ECLAS) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_ECLAS=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\eclass.obj" : $(SOURCE) $(DEP_CPP_ECLAS) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\eclass.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\entity.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_ENTIT=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\entity.obj" : $(SOURCE) $(DEP_CPP_ENTIT) "$(INTDIR)" + +"$(INTDIR)\entity.sbr" : $(SOURCE) $(DEP_CPP_ENTIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_ENTIT=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\entity.obj" : $(SOURCE) $(DEP_CPP_ENTIT) "$(INTDIR)" + +"$(INTDIR)\entity.sbr" : $(SOURCE) $(DEP_CPP_ENTIT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_ENTIT=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\entity.obj" : $(SOURCE) $(DEP_CPP_ENTIT) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_ENTIT=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\entity.obj" : $(SOURCE) $(DEP_CPP_ENTIT) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\entity.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_dlg.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_D=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_dlg.obj" : $(SOURCE) $(DEP_CPP_WIN_D) "$(INTDIR)" + +"$(INTDIR)\win_dlg.sbr" : $(SOURCE) $(DEP_CPP_WIN_D) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_D=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_dlg.obj" : $(SOURCE) $(DEP_CPP_WIN_D) "$(INTDIR)" + +"$(INTDIR)\win_dlg.sbr" : $(SOURCE) $(DEP_CPP_WIN_D) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_D=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_dlg.obj" : $(SOURCE) $(DEP_CPP_WIN_D) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_D=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_dlg.obj" : $(SOURCE) $(DEP_CPP_WIN_D) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\points.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_POINT=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\points.obj" : $(SOURCE) $(DEP_CPP_POINT) "$(INTDIR)" + +"$(INTDIR)\points.sbr" : $(SOURCE) $(DEP_CPP_POINT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_POINT=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\points.obj" : $(SOURCE) $(DEP_CPP_POINT) "$(INTDIR)" + +"$(INTDIR)\points.sbr" : $(SOURCE) $(DEP_CPP_POINT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_POINT=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\points.obj" : $(SOURCE) $(DEP_CPP_POINT) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_POINT=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\points.obj" : $(SOURCE) $(DEP_CPP_POINT) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_z.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_Z=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_z.obj" : $(SOURCE) $(DEP_CPP_WIN_Z) "$(INTDIR)" + +"$(INTDIR)\win_z.sbr" : $(SOURCE) $(DEP_CPP_WIN_Z) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_Z=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_z.obj" : $(SOURCE) $(DEP_CPP_WIN_Z) "$(INTDIR)" + +"$(INTDIR)\win_z.sbr" : $(SOURCE) $(DEP_CPP_WIN_Z) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_Z=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_z.obj" : $(SOURCE) $(DEP_CPP_WIN_Z) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_Z=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_z.obj" : $(SOURCE) $(DEP_CPP_WIN_Z) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\z.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_Z_C26=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\z.obj" : $(SOURCE) $(DEP_CPP_Z_C26) "$(INTDIR)" + +"$(INTDIR)\z.sbr" : $(SOURCE) $(DEP_CPP_Z_C26) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_Z_C26=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\z.obj" : $(SOURCE) $(DEP_CPP_Z_C26) "$(INTDIR)" + +"$(INTDIR)\z.sbr" : $(SOURCE) $(DEP_CPP_Z_C26) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_Z_C26=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\z.obj" : $(SOURCE) $(DEP_CPP_Z_C26) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_Z_C26=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\z.obj" : $(SOURCE) $(DEP_CPP_Z_C26) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\z.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\drag.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_DRAG_=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\drag.obj" : $(SOURCE) $(DEP_CPP_DRAG_) "$(INTDIR)" + +"$(INTDIR)\drag.sbr" : $(SOURCE) $(DEP_CPP_DRAG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_DRAG_=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\drag.obj" : $(SOURCE) $(DEP_CPP_DRAG_) "$(INTDIR)" + +"$(INTDIR)\drag.sbr" : $(SOURCE) $(DEP_CPP_DRAG_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_DRAG_=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\drag.obj" : $(SOURCE) $(DEP_CPP_DRAG_) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_DRAG_=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\drag.obj" : $(SOURCE) $(DEP_CPP_DRAG_) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_main.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_M=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\entityw.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_main.obj" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + +"$(INTDIR)\win_main.sbr" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_M=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\entityw.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_main.obj" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + +"$(INTDIR)\win_main.sbr" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_M=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_main.obj" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_M=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_main.obj" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\csg.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_CSG_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\csg.obj" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + +"$(INTDIR)\csg.sbr" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_CSG_C=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\csg.obj" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + +"$(INTDIR)\csg.sbr" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_CSG_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\csg.obj" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_CSG_C=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\csg.obj" : $(SOURCE) $(DEP_CPP_CSG_C) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\vertsel.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_VERTS=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\vertsel.obj" : $(SOURCE) $(DEP_CPP_VERTS) "$(INTDIR)" + +"$(INTDIR)\vertsel.sbr" : $(SOURCE) $(DEP_CPP_VERTS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_VERTS=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\vertsel.obj" : $(SOURCE) $(DEP_CPP_VERTS) "$(INTDIR)" + +"$(INTDIR)\vertsel.sbr" : $(SOURCE) $(DEP_CPP_VERTS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_VERTS=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\vertsel.obj" : $(SOURCE) $(DEP_CPP_VERTS) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_VERTS=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\vertsel.obj" : $(SOURCE) $(DEP_CPP_VERTS) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\mru.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_MRU_C=\ + ".\mru.h"\ + + +"$(INTDIR)\mru.obj" : $(SOURCE) $(DEP_CPP_MRU_C) "$(INTDIR)" + +"$(INTDIR)\mru.sbr" : $(SOURCE) $(DEP_CPP_MRU_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_MRU_C=\ + ".\mru.h"\ + + +"$(INTDIR)\mru.obj" : $(SOURCE) $(DEP_CPP_MRU_C) "$(INTDIR)" + +"$(INTDIR)\mru.sbr" : $(SOURCE) $(DEP_CPP_MRU_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_MRU_C=\ + ".\mru.h"\ + + +"$(INTDIR)\mru.obj" : $(SOURCE) $(DEP_CPP_MRU_C) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_MRU_C=\ + ".\mru.h"\ + + +"$(INTDIR)\mru.obj" : $(SOURCE) $(DEP_CPP_MRU_C) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_ent.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_WIN_E=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\entityw.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_ent.obj" : $(SOURCE) $(DEP_CPP_WIN_E) "$(INTDIR)" + +"$(INTDIR)\win_ent.sbr" : $(SOURCE) $(DEP_CPP_WIN_E) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_WIN_E=\ + ".\brush.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\entityw.h"\ + ".\glingr.h"\ + ".\lbmlib.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\mru.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\qedefs.h"\ + ".\qfiles.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_ent.obj" : $(SOURCE) $(DEP_CPP_WIN_E) "$(INTDIR)" + +"$(INTDIR)\win_ent.sbr" : $(SOURCE) $(DEP_CPP_WIN_E) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +DEP_CPP_WIN_E=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\entityw.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_ent.obj" : $(SOURCE) $(DEP_CPP_WIN_E) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +DEP_CPP_WIN_E=\ + ".\brush.h"\ + ".\bspfile.h"\ + ".\camera.h"\ + ".\cmdlib.h"\ + ".\entity.h"\ + ".\entityw.h"\ + ".\gl\GL.H"\ + ".\gl\GLAUX.H"\ + ".\gl\GLU.H"\ + ".\glingr.h"\ + ".\map.h"\ + ".\mathlib.h"\ + ".\parse.h"\ + ".\qe3.h"\ + ".\select.h"\ + ".\textures.h"\ + ".\xy.h"\ + ".\z.h"\ + + +"$(INTDIR)\win_ent.obj" : $(SOURCE) $(DEP_CPP_WIN_E) "$(INTDIR)" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\lbmlib.c + +!IF "$(CFG)" == "qe3 - Win32 Release" + +DEP_CPP_LBMLI=\ + ".\cmdlib.h"\ + ".\lbmlib.h"\ + + +"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + +"$(INTDIR)\lbmlib.sbr" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +DEP_CPP_LBMLI=\ + ".\cmdlib.h"\ + ".\lbmlib.h"\ + + +"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + +"$(INTDIR)\lbmlib.sbr" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\qfiles.h + +!IF "$(CFG)" == "qe3 - Win32 Release" + +!ELSEIF "$(CFG)" == "qe3 - Win32 Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Debug" + +!ELSEIF "$(CFG)" == "qe3 - Win32 (ALPHA) Release" + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/tools/quake2/extra/qe4/qedefs.h b/tools/quake2/extra/qe4/qedefs.h new file mode 100644 index 00000000..041aaab6 --- /dev/null +++ b/tools/quake2/extra/qe4/qedefs.h @@ -0,0 +1,117 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#ifndef __QEDEFS_H__ +#define __QEDEFS_H__ + +#define QE_VERSION 0x0401 + +#define QE3_STYLE (WS_OVERLAPPED| WS_CAPTION | WS_THICKFRAME | \ + /* WS_MINIMIZEBOX | */ WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | \ + WS_CLIPCHILDREN | WS_CHILD) + +#define QE_AUTOSAVE_INTERVAL 5 // number of minutes between autosaves + +#define CAMERA_WINDOW_CLASS "QCamera" +#define XY_WINDOW_CLASS "QXY" +#define Z_WINDOW_CLASS "QZ" +#define ENT_WINDOW_CLASS "QENT" + +#define ZWIN_WIDTH 40 +#define CWIN_SIZE (0.4) + +#define MAX_EDGES 256 +#define MAX_POINTS 512 + +#define CMD_TEXTUREWAD 60000 +#define CMD_BSPCOMMAND 61000 + +#define PITCH 0 +#define YAW 1 +#define ROLL 2 + +#define QE_TIMER0 1 + +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +#define ON_EPSILON 0.01 + +#define KEY_FORWARD 1 +#define KEY_BACK 2 +#define KEY_TURNLEFT 4 +#define KEY_TURNRIGHT 8 +#define KEY_LEFT 16 +#define KEY_RIGHT 32 +#define KEY_LOOKUP 64 +#define KEY_LOOKDOWN 128 +#define KEY_UP 256 +#define KEY_DOWN 512 + +// xy.c +#define EXCLUDE_LIGHTS 1 +#define EXCLUDE_ENT 2 +#define EXCLUDE_PATHS 4 +#define EXCLUDE_WATER 8 +#define EXCLUDE_WORLD 16 +#define EXCLUDE_CLIP 32 +#define EXCLUDE_DETAIL 64 + + +// +// menu indexes for modifying menus +// +#define MENU_VIEW 2 +#define MENU_BSP 4 +#define MENU_TEXTURE 6 + + +// odd things not in windows header... +#define VK_COMMA 188 +#define VK_PERIOD 190 + +/* +** window bits +*/ +#define W_CAMERA 0x0001 +#define W_XY 0x0002 +#define W_XY_OVERLAY 0x0004 +#define W_Z 0x0008 +#define W_TEXTURE 0x0010 +#define W_Z_OVERLAY 0x0020 +#define W_CONSOLE 0x0040 +#define W_ENTITY 0x0080 +#define W_ALL 0xFFFFFFFF + +#define COLOR_TEXTUREBACK 0 +#define COLOR_GRIDBACK 1 +#define COLOR_GRIDMINOR 2 +#define COLOR_GRIDMAJOR 3 +#define COLOR_CAMERABACK 4 +#define COLOR_ENTITY 5 +#define COLOR_LAST 6 + +#endif diff --git a/tools/quake2/extra/qe4/qfiles.h b/tools/quake2/extra/qe4/qfiles.h new file mode 100644 index 00000000..e7dbbdfe --- /dev/null +++ b/tools/quake2/extra/qe4/qfiles.h @@ -0,0 +1,389 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// +// qfiles.h: quake file formats +// This file must be identical in the quake and utils directories +// + +/* +======================================================================== + +.MD2 triangle model file format + +======================================================================== +*/ + +#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I') +#define ALIAS_VERSION 8 + +#define MAX_TRIANGLES 4096 +#define MAX_VERTS 2048 +#define MAX_FRAMES 512 +#define MAX_MD2SKINS 32 +#define MAX_SKINNAME 64 + +typedef struct +{ + short s; + short t; +} dstvert_t; + +typedef struct +{ + short index_xyz[3]; + short index_st[3]; +} dtriangle_t; + +typedef struct +{ + byte v[3]; // scaled byte to fit in frame mins/maxs + byte lightnormalindex; +} dtrivertx_t; + +typedef struct +{ + float scale[3]; // multiply byte verts by this + float translate[3]; // then add this + char name[16]; // frame name from grabbing + dtrivertx_t verts[1]; // variable sized +} daliasframe_t; + + +// the glcmd format: +// a positive integer starts a tristrip command, followed by that many +// vertex structures. +// a negative integer starts a trifan command, followed by -x vertexes +// a zero indicates the end of the command list. +// a vertex consists of a floating point s, a floating point t, +// and an integer vertex index. + + +typedef struct +{ + int ident; + int version; + + int skinwidth; + int skinheight; + int framesize; // byte size of each frame + + int num_skins; + int num_xyz; + int num_st; // greater than num_xyz for seams + int num_tris; + int num_glcmds; // dwords in strip/fan command list + int num_frames; + + int ofs_skins; // each skin is a MAX_SKINNAME string + int ofs_st; // byte offset from start for stverts + int ofs_tris; // offset for dtriangles + int ofs_frames; // offset for first frame + int ofs_glcmds; + int ofs_end; // end of file + +} dmdl_t; + +/* +======================================================================== + +.SP2 sprite file format + +======================================================================== +*/ + +#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I') + // little-endian "IDS2" +#define SPRITE_VERSION 2 + +typedef struct +{ + int width, height; + int origin_x, origin_y; // raster coordinates inside pic + char name[MAX_SKINNAME]; // name of pcx file +} dsprframe_t; + +typedef struct { + int ident; + int version; + int numframes; + dsprframe_t frames[1]; // variable sized +} dsprite_t; + +/* +============================================================================== + + .WAL texture file format + +============================================================================== +*/ + + +#define MIPLEVELS 4 +typedef struct miptex_s +{ + char name[32]; + unsigned width, height; + unsigned offsets[MIPLEVELS]; // four mip maps stored + char animname[32]; // next frame in animation chain + int flags; + int contents; + int value; +} miptex_t; + + + +/* +============================================================================== + + .BSP file format + +============================================================================== +*/ + +#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') + // little-endian "IBSP" + +#define BSPVERSION 36 + + +// upper design bounds +// leaffaces, leafbrushes, planes, and verts are still bounded by +// 16 bit short limits +#define MAX_MAP_MODELS 1024 +#define MAX_MAP_BRUSHES 8192 +#define MAX_MAP_ENTITIES 2048 +#define MAX_MAP_ENTSTRING 0x20000 +#define MAX_MAP_TEXINFO 8192 + +#define MAX_MAP_PLANES 65536 +#define MAX_MAP_NODES 65536 +#define MAX_MAP_BRUSHSIDES 65536 +#define MAX_MAP_LEAFS 65536 +#define MAX_MAP_VERTS 65536 +#define MAX_MAP_FACES 65536 +#define MAX_MAP_LEAFFACES 65536 +#define MAX_MAP_LEAFBRUSHES 65536 +#define MAX_MAP_PORTALS 65536 +#define MAX_MAP_EDGES 128000 +#define MAX_MAP_SURFEDGES 256000 +#define MAX_MAP_LIGHTING 0x200000 +#define MAX_MAP_VISIBILITY 0x100000 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + +//============================================================================= + +typedef struct +{ + int fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_PLANES 1 +#define LUMP_VERTEXES 2 +#define LUMP_VISIBILITY 3 +#define LUMP_NODES 4 +#define LUMP_TEXINFO 5 +#define LUMP_FACES 6 +#define LUMP_LIGHTING 7 +#define LUMP_LEAFS 8 +#define LUMP_LEAFFACES 9 +#define LUMP_LEAFBRUSHES 10 +#define LUMP_EDGES 11 +#define LUMP_SURFEDGES 12 +#define LUMP_MODELS 13 +#define LUMP_BRUSHES 14 +#define LUMP_BRUSHSIDES 15 +#define LUMP_POP 16 + +#define HEADER_LUMPS 17 + +typedef struct +{ + int ident; + int version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; // for sounds or lights + int headnode; + int firstface, numfaces; // submodels just draw faces + // without walking the bsp tree +} dmodel_t; + + +typedef struct +{ + float point[3]; +} dvertex_t; + + +// 0-2 are axial planes +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +// 3-5 are non-axial planes snapped to the nearest +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +// planes (x&~1) and (x&~1)+1 are allways opposites + +typedef struct +{ + float normal[3]; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + + +// contents flags are seperate bits +// a given brush can contribute multiple content bits +// multiple brushes can be in a single leaf + +// lower bits are stronger, and will eat weaker brushes completely +#define CONTENTS_SOLID 1 // an eye is never valid in a solid +#define CONTENTS_WINDOW 2 // translucent, but not watery +#define CONTENTS_AUX 4 +#define CONTENTS_LAVA 8 +#define CONTENTS_SLIME 16 +#define CONTENTS_WATER 32 +#define CONTENTS_MIST 64 +#define LAST_VISIBLE_CONTENTS 64 + +// remaining contents are non-visible, and don't eat brushes +#define CONTENTS_PLAYERCLIP 0x10000 +#define CONTENTS_MONSTERCLIP 0x20000 + +// currents can be added to any other contents, and may be mixed +#define CONTENTS_CURRENT_0 0x40000 +#define CONTENTS_CURRENT_90 0x80000 +#define CONTENTS_CURRENT_180 0x100000 +#define CONTENTS_CURRENT_270 0x200000 +#define CONTENTS_CURRENT_UP 0x400000 +#define CONTENTS_CURRENT_DOWN 0x800000 + +#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity + +#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game +#define CONTENTS_DEADMONSTER 0x4000000 +#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs +#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans + + + +typedef struct +{ + int planenum; + int children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for frustom culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides +} dnode_t; + + +typedef struct texinfo_s +{ + float vecs[2][4]; // [s/t][xyz offset] + int flags; // miptex flags + overrides + int value; // light emission, etc + char texture[32]; // texture name (textures/*.wal) + int nexttexinfo; // for animations, -1 = end of chain +} texinfo_t; + + +#define SURF_LIGHT 0x1 // value will hold the light strength + +#define SURF_SLICK 0x2 // effects game physics + +#define SURF_SKY 0x4 // don't draw, but add to skybox +#define SURF_WARP 0x8 // turbulent water warp +#define SURF_TRANS33 0x10 +#define SURF_TRANS66 0x20 +#define SURF_FLOWING 0x40 // scroll towards angle +#define SURF_NODRAW 0x80 // don't bother referencing the texture + + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +typedef struct +{ + unsigned short v[2]; // vertex numbers +} dedge_t; + +#define MAXLIGHTMAPS 4 +typedef struct +{ + unsigned short planenum; + short side; + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dface_t; + +typedef struct +{ + int contents; // OR of all brushes (not needed?) + + int pvsofs; // -1 = no info + int phsofs; // -1 = no info + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstleafface; + unsigned short numleaffaces; + + unsigned short firstleafbrush; + unsigned short numleafbrushes; +} dleaf_t; + +typedef struct +{ + unsigned short planenum; // facing out of the leaf + short texinfo; +} dbrushside_t; + +typedef struct +{ + int firstside; + int numsides; + int contents; +} dbrush_t; + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + diff --git a/tools/quake2/extra/qe4/resource.h b/tools/quake2/extra/qe4/resource.h new file mode 100644 index 00000000..0a65eca2 --- /dev/null +++ b/tools/quake2/extra/qe4/resource.h @@ -0,0 +1,308 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by win_qe3.rc +// +#define IDAPPLY 3 +#define IDR_MENU1 101 +#define IDR_ACCELERATOR1 104 +#define IDD_CREATE_ENTITY 107 +#define IDD_EDIT_ENTITY 108 +#define IDR_TOOLBAR1 109 +#define IDD_FINDTEXTURE 111 +#define IDD_ENTITY 115 +#define IDR_E_MENU 116 +#define IDD_EDITPROP 117 +#define IDD_GAMMA 118 +#define IDD_FINDBRUSH 119 +#define IDI_ICON1 120 +#define IDD_ROTATE 121 +#define IDD_SIDES 122 +#define IDD_ABOUT 123 +#define IDB_BITMAP1 127 +#define IDD_SURFACE 129 +#define IDC_ENTITY_COMMENT 1018 +#define IDC_VALUE 1021 +#define IDC_KEY 1022 +#define IDC_ENTITY_LIST 1023 +#define IDC_PAIRS 1024 +#define IDC_CHECK1 1026 +#define IDC_CHECK2 1027 +#define IDC_CHECK3 1028 +#define IDC_CHECK4 1029 +#define IDC_CHECK5 1030 +#define IDC_CHECK6 1031 +#define IDC_CHECK7 1032 +#define IDC_CHECK8 1033 +#define IDC_CHECK9 1034 +#define IDC_CHECK10 1035 +#define IDC_CHECK11 1036 +#define IDC_CHECK12 1037 +#define IDC_ANGLE90 1038 +#define IDC_CHECK13 1038 +#define IDC_ANGLE45 1039 +#define IDC_CHECK14 1039 +#define IDC_ANGLE135 1040 +#define IDC_CHECK15 1040 +#define IDC_ANGLE225 1041 +#define IDC_CHECK16 1041 +#define IDC_ANGLEUP 1042 +#define IDC_CHECK17 1042 +#define IDC_ANGLE180 1043 +#define IDC_CHECK18 1043 +#define IDC_ANGLE315 1044 +#define IDC_CHECK19 1044 +#define IDC_ANGLE0 1045 +#define IDC_CHECK20 1045 +#define IDC_ANGLE270 1046 +#define IDC_CHECK21 1046 +#define IDC_ANGLEDOWN 1047 +#define IDC_CHECK22 1047 +#define IDC_DELETEKEY 1048 +#define IDC_ADDPAIR 1048 +#define IDC_CHECK23 1048 +#define IDC_DELETEPAIR 1049 +#define IDC_CHECK24 1049 +#define IDC_CHECK25 1050 +#define IDC_SPAWN1 1051 +#define IDC_CHECK26 1051 +#define IDC_SPAWN2 1052 +#define IDC_CHECK27 1052 +#define IDC_SPAWN3 1053 +#define IDC_CHECK28 1053 +#define IDC_SPAWN4 1054 +#define IDC_CHECK29 1054 +#define IDC_SPAWN5 1055 +#define IDC_CHECK30 1055 +#define IDC_SPAWN6 1056 +#define IDC_CHECK31 1056 +#define IDC_SPAWN7 1057 +#define IDC_CHECK32 1057 +#define IDC_SPAWN8 1058 +#define IDC_CHECK33 1058 +#define IDC_EDIT1 1059 +#define IDC_CHECK34 1059 +#define IDC_ROTATE_BOX 1060 +#define IDC_ROTZ 1060 +#define IDC_CHECK35 1060 +#define IDC_SCALE_BOX 1061 +#define IDC_ROTY 1061 +#define IDC_CHECK36 1061 +#define IDC_E_VALUE_FIELD 1062 +#define IDC_CHECK37 1062 +#define IDC_CHECK38 1063 +#define IDC_E_LIST 1064 +#define IDC_CHECK39 1064 +#define IDC_E_COMMENT 1065 +#define IDC_CHECK40 1065 +#define IDC_CHECK41 1066 +#define IDC_E_PROPS 1067 +#define IDC_CHECK42 1067 +#define IDC_E_135 1068 +#define IDC_CHECK43 1068 +#define IDC_E_180 1069 +#define IDC_CHECK44 1069 +#define IDC_E_225 1070 +#define IDC_CHECK45 1070 +#define IDC_E_270 1071 +#define IDC_CHECK46 1071 +#define IDC_E_90 1072 +#define IDC_CHECK47 1072 +#define IDC_E_45 1073 +#define IDC_CHECK48 1073 +#define IDC_E_0 1074 +#define IDC_CHECK49 1074 +#define IDC_E_315 1075 +#define IDC_CHECK50 1075 +#define IDC_E_UP 1076 +#define IDC_CHECK51 1076 +#define IDC_E_DOWN 1077 +#define IDC_CHECK52 1077 +#define IDC_CHECK53 1078 +#define IDC_CHECK54 1079 +#define IDC_E_ADDPROP 1080 +#define IDC_CHECK55 1080 +#define IDC_E_DELPROP 1081 +#define IDC_CHECK56 1081 +#define IDC_E_CREATE 1082 +#define IDC_CHECK57 1082 +#define IDC_E_STATUS 1083 +#define IDC_CHECK58 1083 +#define IDC_CHECK59 1084 +#define IDC_CHECK60 1085 +#define IDC_CHECK61 1086 +#define IDC_CHECK62 1087 +#define IDC_CHECK63 1088 +#define IDC_CHECK64 1089 +#define IDC_SHIFT_BOX 1090 +#define IDC_HSHIFT 1090 +#define IDC_VSHIFT 1091 +#define IDC_ROTATEV 1092 +#define IDC_SCALEV 1093 +#define IDC_SCALEH 1094 +#define IDC_SHIFTV 1095 +#define IDC_HSHIFTA 1095 +#define IDC_SHIFTH 1096 +#define IDC_VSHIFTA 1097 +#define IDC_HSCALE 1098 +#define IDC_HSCALEA 1099 +#define IDC_VSCALE 1100 +#define IDC_VSCALEA 1101 +#define IDC_ROTATE 1102 +#define IDC_G_EDIT 1103 +#define IDC_ROTATEA 1103 +#define IDC_STATIC_KEY 1104 +#define IDC_FIND_BRUSH 1104 +#define IDC_STATIC_VALUE 1105 +#define IDC_E_KEY_FIELD 1106 +#define IDC_FIND_ENTITY 1107 +#define IDC_SIDES 1108 +#define IDC_ROTX 1109 +#define IDC_E_COLOR 1111 +#define IDC_ABOUT_GLVENDOR 1112 +#define IDC_ABOUT_GLVERSION 1113 +#define IDC_ABOUT_GLRENDERER 1114 +#define IDC_TEXTURE 1114 +#define IDC_ABOUT_GLEXTENSIONS 1115 +#define ID_FILE_EXIT 40002 +#define ID_FILE_SAVEAS 40004 +#define ID_VIEW_CENTER 40005 +#define ID_VIEW_UPFLOOR 40006 +#define ID_VIEW_DOWNFLOOR 40007 +#define ID_BRUSH_FLIPX 40008 +#define ID_BRUSH_FLIPY 40009 +#define ID_BRUSH_FLIPZ 40010 +#define ID_BRUSH_ROTATEX 40011 +#define ID_BRUSH_ROTATEY 40012 +#define ID_BRUSH_ROTATEZ 40013 +#define ID_BSP_FULLVIS 40016 +#define ID_BSP_FASTVIS 40017 +#define ID_BSP_NOVIS 40018 +#define ID_BSP_RELIGHT 40019 +#define ID_BSP_ENTITIES 40020 +#define ID_FILE_POINTFILE 40021 +#define ID_VIEW_100 40022 +#define ID_VIEW_75 40023 +#define ID_VIEW_50 40024 +#define ID_VIEW_25 40025 +#define ID_VIEW_12 40026 +#define ID_GRID_1 40028 +#define ID_GRID_2 40029 +#define ID_GRID_4 40030 +#define ID_GRID_8 40031 +#define ID_GRID_16 40032 +#define ID_TEXTURES_SHOWALL 40033 +#define ID_TEXTURES_SHOWINUSE 40034 +#define ID_TEXTURES_TOGGLEVIEW 40037 +#define ID_SELECTION_CREATEENTITY 40039 +#define ID_SELECTION_EDITENTITY 40040 +#define ID_MISC_BENCHMARK 40041 +#define ID_REGION_OFF 40043 +#define ID_REGION_SETXY 40044 +#define ID_REGION_SETBRUSH 40045 +#define ID_SELECTION_MAKEHOLLOW 40046 +#define ID_SELECTION_SELECTPARTIALTALL 40047 +#define ID_SELECTION_SELECTCOMPLETETALL 40048 +#define ID_SELECTION_CSGSUBTRACT 40049 +#define ID_SELECTION_SELECTTOUCHING 40050 +#define ID_VIEW_NEAREST 40052 +#define ID_VIEW_LINEAR 40053 +#define ID_VIEW_BILINEAR 40054 +#define ID_VIEW_TRILINEAR 40055 +#define ID_VIEW_NEARESTMIPMAP 40056 +#define ID_VIEW_BILINEARMIPMAP 40057 +#define ID_VIEW_SHOWNAMES 40058 +#define ID_VIEW_ZOOMIN 40059 +#define ID_VIEW_ZOOMOUT 40060 +#define ID_VIEW_SHOWCOORDINATES 40061 +#define ID_VIEW_Z100 40062 +#define ID_VIEW_ZZOOMIN 40063 +#define ID_VIEW_ZZOOMOUT 40064 +#define ID_SELECTION_CLONE 40065 +#define ID_SELECTION_DESELECT 40066 +#define ID_SELECTION_DELETE 40067 +#define ID_BUTTON40068 40068 +#define ID_TEXTURES_WIREFRAME 40072 +#define ID_TEXTURES_FLATSHADE 40073 +#define ID_SELECTION_DRAGVERTECIES 40074 +#define ID_SELECTION_DRAGEDGES 40075 +#define ID_REGION_SETTALLBRUSH 40076 +#define ID_SELECTION_SELECTINSIDE 40092 +#define ID_PROJECT_RELEAD 40094 +#define ID_PROJECT_CHANGE 40095 +#define ID_MISC_GAMMA 40097 +#define ID_VIEW_SHOWENT 40098 +#define ID_VIEW_SHOWPATH 40099 +#define ID_VIEW_SHOWLIGHTS 40100 +#define ID_VIEW_SHOWCLIP 40101 +#define ID_VIEW_SHOWWATER 40102 +#define ID_VIEW_SHOWWORLD 40103 +#define ID_MISC_TEXTUREBACKGROUN 40104 +#define ID_TEXTUREBK 40105 +#define ID_COLORS_XYBK 40106 +#define ID_FILE_ABOUT 40107 +#define ID_VIEW_CONSOLE 40108 +#define ID_VIEW_ENTITY 40109 +#define ID_VIEW_TEXTURE 40110 +#define ID_COLORS_MAJOR 40111 +#define ID_COLORS_MINOR 40113 +#define ID_SELECTION_CONNECT 40114 +#define ID_FILE_LOADPROJECT 40115 +#define ID_MISC_FINDBRUSH 40116 +#define ID_MISC_NEXTLEAKSPOT 40117 +#define ID_MISC_PREVIOUSLEAKSPOT 40118 +#define ID_BRUSH_3SIDED 40119 +#define ID_BRUSH_4SIDED 40120 +#define ID_BRUSH_5SIDED 40121 +#define ID_BRUSH_6SIDED 40122 +#define ID_BRUSH_7SIDED 40123 +#define ID_BRUSH_8SIDED 40124 +#define ID_BRUSH_9SIDED 40125 +#define ID_SELECTION_ARBITRARYROTATION 40126 +#define ID_BRUSH_ARBITRARYSIDED 40127 +#define ID_GRID_32 40128 +#define ID_GRID_64 40129 +#define ID_SELECTION_UNGROUPENTITY 40130 +#define ID_MISC_SELECTENTITYCOLOR 40131 +#define ID_MISC_PRINTXY 40132 +#define ID_HELP_ABOUT 40134 +#define ID_EDIT_COPYBRUSH 40135 +#define ID_EDIT_PASTEBRUSH 40136 +#define ID_TEXTURES_INSPECTOR 40137 +#define ID_VIEW_SHOWDETAIL 40138 +#define ID_SELECTION_MAKE_DETAIL 40139 +#define ID_SELECTION_MAKE_STRUCTURAL 40140 +#define ID_REGION_SETSELECTION 40142 +#define ID_VIEW_SHOWBLOCKS 40143 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 130 +#define _APS_NEXT_COMMAND_VALUE 40144 +#define _APS_NEXT_CONTROL_VALUE 1115 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/tools/quake2/extra/qe4/select.c b/tools/quake2/extra/qe4/select.c new file mode 100644 index 00000000..2761ecb3 --- /dev/null +++ b/tools/quake2/extra/qe4/select.c @@ -0,0 +1,706 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// select.c + +#include "qe3.h" + +/* +=========== +Test_Ray +=========== +*/ +#define DIST_START 999999 +trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags) +{ + brush_t *brush; + face_t *face; + float dist; + trace_t t; + + memset (&t, 0, sizeof(t)); + t.dist = DIST_START; + + if (! (flags & SF_SELECTED_ONLY) ) + for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) + { + if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) + continue; + if (FilterBrush (brush)) + continue; + face = Brush_Ray (origin, dir, brush, &dist); + if (dist > 0 && dist < t.dist) + { + t.dist = dist; + t.brush = brush; + t.face = face; + t.selected = false; + } + } + for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) + { + if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) + continue; + if (FilterBrush (brush)) + continue; + face = Brush_Ray (origin, dir, brush, &dist); + if (dist > 0 && dist < t.dist) + { + t.dist = dist; + t.brush = brush; + t.face = face; + t.selected = true; + } + } + + // if entites first, but didn't find any, check regular + + if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL) + return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST); + + return t; +} + + +/* +============ +Select_Brush + +============ +*/ +void Select_Brush (brush_t *brush) +{ + brush_t *b; + entity_t *e; + + selected_face = NULL; + if (g_qeglobals.d_select_count < 2) + g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush; + g_qeglobals.d_select_count++; + + e = brush->owner; + if (e) + { + // select complete entity on first click + if (e != world_entity) + { + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + if (b->owner == e) + goto singleselect; + for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext) + { + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + } + } + else + { +singleselect: + Brush_RemoveFromList (brush); + Brush_AddToList (brush, &selected_brushes); + } + + if (e->eclass) + { + UpdateEntitySel(brush->owner->eclass); + } + } +} + +/* +============ +Select_Ray + +If the origin is inside a brush, that brush will be ignored. +============ +*/ +void Select_Ray (vec3_t origin, vec3_t dir, int flags) +{ + trace_t t; + + t = Test_Ray (origin, dir, flags); + if (!t.brush) + return; + + if (flags == SF_SINGLEFACE) + { + selected_face = t.face; + selected_face_brush = t.brush; + Sys_UpdateWindows (W_ALL); + g_qeglobals.d_select_mode = sel_brush; + return; + } + + // move the brush to the other list + + g_qeglobals.d_select_mode = sel_brush; + + if (t.selected) + { + Brush_RemoveFromList (t.brush); + Brush_AddToList (t.brush, &active_brushes); + } else + { + Select_Brush (t.brush); + } + + Sys_UpdateWindows (W_ALL); +} + + +void Select_Delete (void) +{ + brush_t *brush; + + selected_face = NULL; + g_qeglobals.d_select_mode = sel_brush; + + g_qeglobals.d_select_count = 0; + g_qeglobals.d_num_move_points = 0; + while (selected_brushes.next != &selected_brushes) + { + brush = selected_brushes.next; + Brush_Free (brush); + } + + // FIXME: remove any entities with no brushes + + Sys_UpdateWindows (W_ALL); +} + +void Select_Deselect (void) +{ + brush_t *b; + + g_qeglobals.d_workcount++; + g_qeglobals.d_select_count = 0; + g_qeglobals.d_num_move_points = 0; + b = selected_brushes.next; + + if (b == &selected_brushes) + { + if (selected_face) + { + selected_face = NULL; + Sys_UpdateWindows (W_ALL); + } + return; + } + + selected_face = NULL; + g_qeglobals.d_select_mode = sel_brush; + + // grab top / bottom height for new brushes + if (b->mins[2] < b->maxs[2]) + { + g_qeglobals.d_new_brush_bottom_z = b->mins[2]; + g_qeglobals.d_new_brush_top_z = b->maxs[2]; + } + + selected_brushes.next->prev = &active_brushes; + selected_brushes.prev->next = active_brushes.next; + active_brushes.next->prev = selected_brushes.prev; + active_brushes.next = selected_brushes.next; + selected_brushes.prev = selected_brushes.next = &selected_brushes; + + Sys_UpdateWindows (W_ALL); +} + +/* +============ +Select_Move +============ +*/ +void Select_Move (vec3_t delta) +{ + brush_t *b; + +// actually move the selected brushes + for (b = selected_brushes.next ; b != &selected_brushes ; b=b->next) + Brush_Move (b, delta); +// Sys_UpdateWindows (W_ALL); +} + +/* +============ +Select_Clone + +Creates an exact duplicate of the selection in place, then moves +the selected brushes off of their old positions +============ +*/ +void Select_Clone (void) +{ + brush_t *b, *b2, *n, *next, *next2; + vec3_t delta; + entity_t *e; + + g_qeglobals.d_workcount++; + g_qeglobals.d_select_mode = sel_brush; + + delta[0] = g_qeglobals.d_gridsize; + delta[1] = g_qeglobals.d_gridsize; + delta[2] = 0; + + for (b=selected_brushes.next ; b != &selected_brushes ; b=next) + { + next = b->next; + // if the brush is a world brush, handle simply + if (b->owner == world_entity) + { + n = Brush_Clone (b); + Brush_AddToList (n, &active_brushes); + Entity_LinkBrush (world_entity, n); + Brush_Build( n ); + Brush_Move (b, delta); + continue; + } + + e = Entity_Clone (b->owner); + // clear the target / targetname + DeleteKey (e, "target"); + DeleteKey (e, "targetname"); + + // if the brush is a fixed size entity, create a new entity + if (b->owner->eclass->fixedsize) + { + n = Brush_Clone (b); + Brush_AddToList (n, &active_brushes); + Entity_LinkBrush (e, n); + Brush_Build( n ); + Brush_Move (b, delta); + continue; + } + + // brush is a complex entity, grab all the other ones now + + next = &selected_brushes; + + for ( b2 = b ; b2 != &selected_brushes ; b2=next2) + { + next2 = b2->next; + if (b2->owner != b->owner) + { + if (next == &selected_brushes) + next = b2; + continue; + } + + // move b2 to the start of selected_brushes, + // so it won't be hit again + Brush_RemoveFromList (b2); + Brush_AddToList (b2, &selected_brushes); + + n = Brush_Clone (b2); + Brush_AddToList (n, &active_brushes); + Entity_LinkBrush (e, n); + Brush_Build( n ); + Brush_Move (b2, delta); + } + + } + Sys_UpdateWindows (W_ALL); +} + + + +/* +============ +Select_SetTexture +============ +*/ +void Select_SetTexture (texdef_t *texdef) +{ + brush_t *b; + + if (selected_face) + { + selected_face->texdef = *texdef; + Brush_Build(selected_face_brush); + } + else + { + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + if (!b->owner->eclass->fixedsize) + Brush_SetTexture (b, texdef); + } + Sys_UpdateWindows (W_ALL); +} + + +/* +================================================================ + + TRANSFORMATIONS + +================================================================ +*/ + +void Select_GetBounds (vec3_t mins, vec3_t maxs) +{ + brush_t *b; + int i; + + for (i=0 ; i<3 ; i++) + { + mins[i] = 99999; + maxs[i] = -99999; + } + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + for (i=0 ; i<3 ; i++) + { + if (b->mins[i] < mins[i]) + mins[i] = b->mins[i]; + if (b->maxs[i] > maxs[i]) + maxs[i] = b->maxs[i]; + } +} + +void Select_GetMid (vec3_t mid) +{ + vec3_t mins, maxs; + int i; + + Select_GetBounds (mins, maxs); + for (i=0 ; i<3 ; i++) + mid[i] = g_qeglobals.d_gridsize*floor ( ( (mins[i] + maxs[i])*0.5 )/g_qeglobals.d_gridsize ); +} + +vec3_t select_origin; +vec3_t select_matrix[3]; +qboolean select_fliporder; + +void Select_AplyMatrix (void) +{ + brush_t *b; + face_t *f; + int i, j; + vec3_t temp; + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + { + for (f=b->brush_faces ; f ; f=f->next) + { + for (i=0 ; i<3 ; i++) + { + VectorSubtract (f->planepts[i], select_origin, temp); + for (j=0 ; j<3 ; j++) + f->planepts[i][j] = DotProduct(temp, select_matrix[j]) + + select_origin[j]; + } + if (select_fliporder) + { + VectorCopy (f->planepts[0], temp); + VectorCopy (f->planepts[2], f->planepts[0]); + VectorCopy (temp, f->planepts[2]); + } + } + Brush_Build( b ); + } + Sys_UpdateWindows (W_ALL); +} + + +void Select_FlipAxis (int axis) +{ + int i; + + Select_GetMid (select_origin); + for (i=0 ; i<3 ; i++) + { + VectorCopy (vec3_origin, select_matrix[i]); + select_matrix[i][i] = 1; + } + select_matrix[axis][axis] = -1; + + select_fliporder = true; + Select_AplyMatrix (); +} + +void Select_RotateAxis (int axis, float deg) +{ + vec3_t temp; + int i, j; + vec_t c, s; + + if (deg == 0) + return; + + Select_GetMid (select_origin); + select_fliporder = false; + + if (deg == 90) + { + for (i=0 ; i<3 ; i++) + { + VectorCopy (vec3_origin, select_matrix[i]); + select_matrix[i][i] = 1; + } + i = (axis+1)%3; + j = (axis+2)%3; + VectorCopy (select_matrix[i], temp); + VectorCopy (select_matrix[j], select_matrix[i]); + VectorSubtract (vec3_origin, temp, select_matrix[j]); + } + else + { + deg = -deg; + if (deg == -180) + { + c = -1; + s = 0; + } + else if (deg == -270) + { + c = 0; + s = -1; + } + else + { + c = cos(deg/180*3.14159); + s = sin (deg/180*3.14159); + } + + for (i=0 ; i<3 ; i++) + { + VectorCopy (vec3_origin, select_matrix[i]); + select_matrix[i][i] = 1; + } + + switch (axis) + { + case 0: + select_matrix[1][1] = c; + select_matrix[1][2] = -s; + select_matrix[2][1] = s; + select_matrix[2][2] = c; + break; + case 1: + select_matrix[0][0] = c; + select_matrix[0][2] = s; + select_matrix[2][0] = -s; + select_matrix[2][2] = c; + break; + case 2: + select_matrix[0][0] = c; + select_matrix[0][1] = -s; + select_matrix[1][0] = s; + select_matrix[1][1] = c; + break; + } + } + + Select_AplyMatrix (); +} + +/* +================================================================ + +GROUP SELECTIONS + +================================================================ +*/ + +void Select_CompleteTall (void) +{ + brush_t *b, *next; + int i; + vec3_t mins, maxs; + + if (!QE_SingleBrush ()) + return; + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy (selected_brushes.next->mins, mins); + VectorCopy (selected_brushes.next->maxs, maxs); + Select_Delete (); + + for (b=active_brushes.next ; b != &active_brushes ; b=next) + { + next = b->next; + for (i=0 ; i<2 ; i++) + if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i]) + break; + if (i == 2) + { + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + } + } + Sys_UpdateWindows (W_ALL); +} + +void Select_PartialTall (void) +{ + brush_t *b, *next; + int i; + vec3_t mins, maxs; + + if (!QE_SingleBrush ()) + return; + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy (selected_brushes.next->mins, mins); + VectorCopy (selected_brushes.next->maxs, maxs); + Select_Delete (); + + for (b=active_brushes.next ; b != &active_brushes ; b=next) + { + next = b->next; + for (i=0 ; i<2 ; i++) + if (b->mins[i] > maxs[i] || b->maxs[i] < mins[i]) + break; + if (i == 2) + { + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + } + } + Sys_UpdateWindows (W_ALL); +} + +void Select_Touching (void) +{ + brush_t *b, *next; + int i; + vec3_t mins, maxs; + + if (!QE_SingleBrush ()) + return; + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy (selected_brushes.next->mins, mins); + VectorCopy (selected_brushes.next->maxs, maxs); + + for (b=active_brushes.next ; b != &active_brushes ; b=next) + { + next = b->next; + for (i=0 ; i<3 ; i++) + if (b->mins[i] > maxs[i]+1 || b->maxs[i] < mins[i]-1) + break; + if (i == 3) + { + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + } + } + Sys_UpdateWindows (W_ALL); +} + +void Select_Inside (void) +{ + brush_t *b, *next; + int i; + vec3_t mins, maxs; + + if (!QE_SingleBrush ()) + return; + + g_qeglobals.d_select_mode = sel_brush; + + VectorCopy (selected_brushes.next->mins, mins); + VectorCopy (selected_brushes.next->maxs, maxs); + Select_Delete (); + + for (b=active_brushes.next ; b != &active_brushes ; b=next) + { + next = b->next; + for (i=0 ; i<3 ; i++) + if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i]) + break; + if (i == 3) + { + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + } + } + Sys_UpdateWindows (W_ALL); +} + +/* +============= +Select_Ungroup + +Turn the currently selected entity back into normal brushes +============= +*/ +void Select_Ungroup (void) +{ + entity_t *e; + brush_t *b; + + e = selected_brushes.next->owner; + + if (!e || e == world_entity || e->eclass->fixedsize) + { + Sys_Status ("Not a grouped entity.", 0); + return; + } + + for (b=e->brushes.onext ; b != &e->brushes ; b=e->brushes.onext) + { + Brush_RemoveFromList (b); + Brush_AddToList (b, &active_brushes); + Entity_UnlinkBrush (b); + Entity_LinkBrush (world_entity, b); + Brush_Build( b ); + b->owner = world_entity; + } + + Entity_Free (e); + Sys_UpdateWindows (W_ALL); +} + +/* +==================== +Select_MakeStructural +==================== +*/ +void Select_MakeStructural (void) +{ + brush_t *b; + face_t *f; + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + for (f=b->brush_faces ; f ; f=f->next) + f->texdef.contents &= ~CONTENTS_DETAIL; + Select_Deselect (); + Sys_UpdateWindows (W_ALL); +} + +void Select_MakeDetail (void) +{ + brush_t *b; + face_t *f; + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + for (f=b->brush_faces ; f ; f=f->next) + f->texdef.contents |= CONTENTS_DETAIL; + Select_Deselect (); + Sys_UpdateWindows (W_ALL); +} + + diff --git a/tools/quake2/extra/qe4/select.h b/tools/quake2/extra/qe4/select.h new file mode 100644 index 00000000..003902a2 --- /dev/null +++ b/tools/quake2/extra/qe4/select.h @@ -0,0 +1,62 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +typedef enum +{ + sel_brush, + // sel_sticky_brush, + // sel_face, + sel_vertex, + sel_edge +} select_t; + +typedef struct +{ + brush_t *brush; + face_t *face; + float dist; + qboolean selected; +} trace_t; + +#define SF_SELECTED_ONLY 1 +#define SF_ENTITIES_FIRST 2 +#define SF_SINGLEFACE 4 + + +trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags); + +void Select_GetBounds (vec3_t mins, vec3_t maxs); +void Select_Brush (brush_t *b); +void Select_Ray (vec3_t origin, vec3_t dir, int flags); +void Select_Delete (void); +void Select_Deselect (void); +void Select_Clone (void); +void Select_Move (vec3_t delta); +void Select_SetTexture (texdef_t *texdef); +void Select_FlipAxis (int axis); +void Select_RotateAxis (int axis, float deg); +void Select_CompleteTall (void); +void Select_PartialTall (void); +void Select_Touching (void); +void Select_Inside (void); +void Select_MakeStructural (void); +void Select_MakeDetail (void); diff --git a/tools/quake2/extra/qe4/textures.c b/tools/quake2/extra/qe4/textures.c new file mode 100644 index 00000000..21fa8ce0 --- /dev/null +++ b/tools/quake2/extra/qe4/textures.c @@ -0,0 +1,1147 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" +#include "io.h" + +#define TYP_MIPTEX 68 +static unsigned tex_palette[256]; + +static qtexture_t *notexture; + +static qboolean nomips; + +#define FONT_HEIGHT 10 + +static HGLRC s_hglrcTexture; +static HDC s_hdcTexture; + +//int texture_mode = GL_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; +//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; +//int texture_mode = GL_LINEAR; +//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; +int texture_mode = GL_LINEAR_MIPMAP_LINEAR; + +int texture_extension_number = 1; + +// current active texture directory. if empty, show textures in use +char texture_directory[32]; // use if texture_showinuse is false +qboolean texture_showinuse; + +// texture layout functions +qtexture_t *current_texture; +int current_x, current_y, current_row; + +int texture_nummenus; +#define MAX_TEXTUREDIRS 100 +char texture_menunames[MAX_TEXTUREDIRS][64]; + +qboolean g_dontuse; // set to true to load the texture but not flag as used + +void SelectTexture (int mx, int my); + +void Texture_MouseDown (int x, int y, int buttons); +void Texture_MouseUp (int x, int y, int buttons); +void Texture_MouseMoved (int x, int y, int buttons); + +//===================================================== + +void SortTextures(void) +{ + qtexture_t *q, *qtemp, *qhead, *qcur, *qprev; + + // standard insertion sort + // Take the first texture from the list and + // add it to our new list + if ( g_qeglobals.d_qtextures == NULL) + return; + + qhead = g_qeglobals.d_qtextures; + q = g_qeglobals.d_qtextures->next; + qhead->next = NULL; + + // while there are still things on the old + // list, keep adding them to the new list + while (q) + { + qtemp = q; + q = q->next; + + qprev = NULL; + qcur = qhead; + + while (qcur) + { + // Insert it here? + if (strcmp(qtemp->name, qcur->name) < 0) + { + qtemp->next = qcur; + if (qprev) + qprev->next = qtemp; + else + qhead = qtemp; + break; + } + + // Move on + + qprev = qcur; + qcur = qcur->next; + + + // is this one at the end? + + if (qcur == NULL) + { + qprev->next = qtemp; + qtemp->next = NULL; + } + } + + + } + + g_qeglobals.d_qtextures = qhead; +} + +//===================================================== + + +/* +============== +Texture_InitPalette +============== +*/ +void Texture_InitPalette (byte *pal) +{ + int r,g,b,v; + int i; + int inf; + byte gammatable[256]; + float gamma; + + gamma = g_qeglobals.d_savedinfo.fGamma; + + if (gamma == 1.0) + { + for (i=0 ; i<256 ; i++) + gammatable[i] = i; + } + else + { + for (i=0 ; i<256 ; i++) + { + inf = 255 * pow ( (i+0.5)/255.5 , gamma ) + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + gammatable[i] = inf; + } + } + + for (i=0 ; i<256 ; i++) + { + r = gammatable[pal[0]]; + g = gammatable[pal[1]]; + b = gammatable[pal[2]]; + pal += 3; + + v = (r<<24) + (g<<16) + (b<<8) + 255; + v = BigLong (v); + + tex_palette[i] = v; + } +} + +void SetTexParameters (void) +{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode ); + + switch ( texture_mode ) + { + case GL_NEAREST: + case GL_NEAREST_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + break; + case GL_LINEAR: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_LINEAR: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + break; + } +} + +/* +============ +Texture_SetMode +============ +*/ +void Texture_SetMode(int iMenu) +{ + int i, iMode; + HMENU hMenu; + qboolean texturing = true; + + hMenu = GetMenu(g_qeglobals.d_hwndMain); + + switch(iMenu) { + case ID_VIEW_NEAREST: + iMode = GL_NEAREST; + break; + case ID_VIEW_NEARESTMIPMAP: + iMode = GL_NEAREST_MIPMAP_NEAREST; + break; + case ID_VIEW_LINEAR: + iMode = GL_NEAREST_MIPMAP_LINEAR; + break; + case ID_VIEW_BILINEAR: + iMode = GL_LINEAR; + break; + case ID_VIEW_BILINEARMIPMAP: + iMode = GL_LINEAR_MIPMAP_NEAREST; + break; + case ID_VIEW_TRILINEAR: + iMode = GL_LINEAR_MIPMAP_LINEAR; + break; + + case ID_TEXTURES_WIREFRAME: + iMode = 0; + texturing = false; + break; + + case ID_TEXTURES_FLATSHADE: + iMode = 0; + texturing = false; + break; + + } + + CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED); + + CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED); + + g_qeglobals.d_savedinfo.iTexMenu = iMenu; + texture_mode = iMode; + if ( texturing ) + SetTexParameters (); + + if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME) + { + camera.draw_mode = cd_wire; + Map_BuildBrushData(); + Sys_UpdateWindows (W_ALL); + return; + + } else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) { + + camera.draw_mode = cd_solid; + Map_BuildBrushData(); + Sys_UpdateWindows (W_ALL); + return; + } + + for (i=1 ; iwidth); + height = LittleLong(qtex->height); + + q->width = width; + q->height = height; + + q->flags = qtex->flags; + q->value = qtex->value; + q->contents = qtex->contents; + + dest = qmalloc (width*height*4); + + count = width*height; + source = (byte *)qtex + LittleLong(qtex->offsets[0]); + + // The dib is upside down so we want to copy it into + // the buffer bottom up. + + total[0] = total[1] = total[2] = 0; + for (i=0 ; icolor[0] = (float)total[0]/(count*255); + q->color[1] = (float)total[1]/(count*255); + q->color[2] = (float)total[2]/(count*255); + + q->texture_number = texture_extension_number++; + + glBindTexture( GL_TEXTURE_2D, q->texture_number ); + SetTexParameters (); + + if (nomips) + glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest); + else + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest); + + free (dest); + + glBindTexture( GL_TEXTURE_2D, 0 ); + + return q; +} + +/* +=============== +Texture_CreateSolid + +Create a single pixel texture of the apropriate color +=============== +*/ +qtexture_t *Texture_CreateSolid (char *name) +{ + byte data[4]; + qtexture_t *q; + + q = qmalloc(sizeof(*q)); + + sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]); + + data[0] = q->color[0]*255; + data[1] = q->color[1]*255; + data[2] = q->color[2]*255; + data[3] = 255; + + q->width = q->height = 1; + q->texture_number = texture_extension_number++; + glBindTexture( GL_TEXTURE_2D, q->texture_number ); + SetTexParameters (); + + if (nomips) + glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + else + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data); + + glBindTexture( GL_TEXTURE_2D, 0 ); + + return q; +} + + +/* +================= +Texture_MakeNotexture +================= +*/ +void Texture_MakeNotexture (void) +{ + qtexture_t *q; + byte data[4][4]; + + notexture = q = qmalloc(sizeof(*q)); + strcpy (q->name, "notexture"); + q->width = q->height = 64; + + memset (data, 0, sizeof(data)); + data[0][2] = data[3][2] = 255; + + q->color[0] = 0; + q->color[1] = 0; + q->color[2] = 0.5; + + q->texture_number = texture_extension_number++; + glBindTexture( GL_TEXTURE_2D, q->texture_number ); + SetTexParameters (); + + if (nomips) + glTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + else + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data); + + glBindTexture( GL_TEXTURE_2D, 0 ); +} + + + +/* +=============== +Texture_ForName +=============== +*/ +qtexture_t *Texture_ForName (char *name) +{ + byte *lump; + qtexture_t *q; + char filename[1024]; + +//return notexture; + for (q=g_qeglobals.d_qtextures ; q ; q=q->next) + { + if (!strcmp(name, q->name)) + { + if (!g_dontuse) + q->inuse = true; + return q; + } + } + + if (name[0] == '(') + { + q = Texture_CreateSolid (name); + strncpy (q->name, name, sizeof(q->name)-1); + } + else + { + // load the file + sprintf (filename, "%s/%s.wal", + ValueForKey (g_qeglobals.d_project_entity, "texturepath"), + name); + Sys_Printf ("Loading %s\n", name); + if (LoadFile (filename, &lump) == -1) + { + Sys_Printf (" load failed!\n"); + return notexture; + } + q = Texture_LoadTexture ((miptex_t *)lump); + free (lump); + strncpy (q->name, name, sizeof(q->name)-1); + StripExtension (q->name); + } + + if (!g_dontuse) + q->inuse = true; + q->next = g_qeglobals.d_qtextures; + g_qeglobals.d_qtextures = q; + + return q; +} + +/* +================== +FillTextureMenu + +================== +*/ +void FillTextureMenu (void) +{ + HMENU hmenu; + int i; + struct _finddata_t fileinfo; + int handle; + char dirstring[1024]; + char *path; + + hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE); + + // delete everything + for (i=0 ; inext) + { + q->inuse = false; + } +} + + + +/* +============== +Texture_ShowDirectory +============== +*/ +void Texture_ShowDirectory (int menunum) +{ + struct _finddata_t fileinfo; + int handle; + char name[1024]; + char dirstring[1024]; + + texture_showinuse = false; + strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]); + + g_qeglobals.d_texturewin.originy = 0; + Sys_Status("loading all textures\n", 0); + + // load all .wal files + sprintf (dirstring, "%s/textures/%s*.wal", + ValueForKey (g_qeglobals.d_project_entity, "basepath"), + texture_menunames[menunum-CMD_TEXTUREWAD]); + + Sys_Printf ("Scanning %s\n", dirstring); + + handle = _findfirst (dirstring, &fileinfo); + if (handle == -1) + return; + + g_dontuse = true; + do + { + sprintf (name, "%s%s", texture_directory, fileinfo.name); + StripExtension (name); + Texture_ForName (name); + } while (_findnext( handle, &fileinfo ) != -1); + g_dontuse = false; + + _findclose (handle); + + SortTextures(); + SetInspectorMode(W_TEXTURE); + Sys_UpdateWindows(W_TEXTURE); + + sprintf (name, "Textures: %s", texture_directory); + SetWindowText(g_qeglobals.d_hwndEntity, name); + + // select the first texture in the list + if (!g_qeglobals.d_texturewin.texdef.name[0]) + SelectTexture (16, g_qeglobals.d_texturewin.height -16); +} + +/* +============== +Texture_ShowInuse +============== +*/ +void Texture_ShowInuse (void) +{ + char name[1024]; + face_t *f; + brush_t *b; + + texture_showinuse = true; + + g_qeglobals.d_texturewin.originy = 0; + Sys_Status("Selecting active textures\n", 0); + Texture_ClearInuse (); + + for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next) + for (f=b->brush_faces ; f ; f=f->next) + Texture_ForName (f->texdef.name); + + for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next) + for (f=b->brush_faces ; f ; f=f->next) + Texture_ForName (f->texdef.name); + + SortTextures(); + SetInspectorMode(W_TEXTURE); + Sys_UpdateWindows (W_TEXTURE); + + sprintf (name, "Textures: in use"); + SetWindowText(g_qeglobals.d_hwndEntity, name); + + // select the first texture in the list + if (!g_qeglobals.d_texturewin.texdef.name[0]) + SelectTexture (16, g_qeglobals.d_texturewin.height -16); +} + +/* +============================================================================ + +TEXTURE LAYOUT + +============================================================================ +*/ + +void Texture_StartPos (void) +{ + current_texture = g_qeglobals.d_qtextures; + current_x = 8; + current_y = -8; + current_row = 0; +} + +qtexture_t *Texture_NextPos (int *x, int *y) +{ + qtexture_t *q; + + while (1) + { + q = current_texture; + if (!q) + return q; + current_texture = current_texture->next; + if (q->name[0] == '(') // fake color texture + continue; + if (q->inuse) + break; // allways show in use + if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory))) + continue; + break; + } + + if (current_x + q->width > g_qeglobals.d_texturewin.width-8 && current_row) + { // go to the next row unless the texture is the first on the row + current_x = 8; + current_y -= current_row + FONT_HEIGHT + 4; + current_row = 0; + } + + *x = current_x; + *y = current_y; + + // Is our texture larger than the row? If so, grow the + // row height to match it + + if (current_row < q->height) + current_row = q->height; + + // never go less than 64, or the names get all crunched up + current_x += q->width < 64 ? 64 : q->width; + current_x += 8; + + return q; +} + +/* +============================================================================ + + MOUSE ACTIONS + +============================================================================ +*/ + +static int textures_cursorx, textures_cursory; + + +/* +============ +Texture_SetTexture + +============ +*/ +void Texture_SetTexture (texdef_t *texdef) +{ + qtexture_t *q; + int x,y; + char sz[256]; + + if (texdef->name[0] == '(') + { + Sys_Status("Can't select an entity texture\n", 0); + return; + } + g_qeglobals.d_texturewin.texdef = *texdef; + + Sys_UpdateWindows (W_TEXTURE); + sprintf(sz, "Selected texture: %s\n", texdef->name); + Sys_Status(sz, 0); + Select_SetTexture(texdef); + +// scroll origin so the texture is completely on screen + Texture_StartPos (); + while (1) + { + q = Texture_NextPos (&x, &y); + if (!q) + break; + if (!strcmpi(texdef->name, q->name)) + { + if (y > g_qeglobals.d_texturewin.originy) + { + g_qeglobals.d_texturewin.originy = y; + Sys_UpdateWindows (W_TEXTURE); + return; + } + + if (y-q->height-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height) + { + g_qeglobals.d_texturewin.originy = y-q->height-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height; + Sys_UpdateWindows (W_TEXTURE); + return; + } + + return; + } + } +} + + +/* +============== +SelectTexture + + By mouse click +============== +*/ +void SelectTexture (int mx, int my) +{ + int x, y; + qtexture_t *q; + texdef_t tex; + + my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height; + + Texture_StartPos (); + while (1) + { + q = Texture_NextPos (&x, &y); + if (!q) + break; + if (mx > x && mx - x < q->width + && my < y && y - my < q->height + FONT_HEIGHT) + { + memset (&tex, 0, sizeof(tex)); + tex.scale[0] = 1; + tex.scale[1] = 1; + tex.flags = q->flags; + tex.value = q->value; + tex.contents = q->contents; + strcpy (tex.name, q->name); + Texture_SetTexture (&tex); + return; + } + } + + Sys_Status("Did not select a texture\n", 0); +} + +/* +============== +Texture_MouseDown +============== +*/ +void Texture_MouseDown (int x, int y, int buttons) +{ + Sys_GetCursorPos (&textures_cursorx, &textures_cursory); + + // lbutton = select texture + if (buttons == MK_LBUTTON ) + { + SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y); + return; + } + +} + +/* +============== +Texture_MouseUp +============== +*/ +void Texture_MouseUp (int x, int y, int buttons) +{ +} + +/* +============== +Texture_MouseMoved +============== +*/ +void Texture_MouseMoved (int x, int y, int buttons) +{ + int scale = 1; + + if ( buttons & MK_SHIFT ) + scale = 4; + + // rbutton = drag texture origin + if (buttons & MK_RBUTTON) + { + Sys_GetCursorPos (&x, &y); + if ( y != textures_cursory) + { + g_qeglobals.d_texturewin.originy += ( y-textures_cursory) * scale; + if (g_qeglobals.d_texturewin.originy > 0) + g_qeglobals.d_texturewin.originy = 0; + Sys_SetCursorPos (textures_cursorx, textures_cursory); + Sys_UpdateWindows (W_TEXTURE); + } + return; + } +} + + +/* +============================================================================ + +DRAWING + +============================================================================ +*/ + +int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; } +HFONT ghFont = NULL; + +/* +============ +Texture_Draw2 +============ +*/ +void Texture_Draw2 (int width, int height) +{ + qtexture_t *q; + int x, y; + char *name; + + glClearColor ( + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0], + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1], + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2], + 0); + glViewport (0,0,width,height); + glClear (GL_COLOR_BUFFER_BIT); + glDisable (GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + glOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100); + glEnable (GL_TEXTURE_2D); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + g_qeglobals.d_texturewin.width = width; + g_qeglobals.d_texturewin.height = height; + Texture_StartPos (); + + while (1) + { + q = Texture_NextPos (&x, &y); + if (!q) + break; + + // Is this texture visible? + if ( (y-q->height-FONT_HEIGHT < g_qeglobals.d_texturewin.originy) + && (y > g_qeglobals.d_texturewin.originy - height) ) + { + + // if in use, draw a background + if (q->inuse && !texture_showinuse) + { + glLineWidth (1); + glColor3f (0.5,1,0.5); + glDisable (GL_TEXTURE_2D); + + glBegin (GL_LINE_LOOP); + glVertex2f (x-1,y+1-FONT_HEIGHT); + glVertex2f (x-1,y-q->height-1-FONT_HEIGHT); + glVertex2f (x+1+q->width,y-q->height-1-FONT_HEIGHT); + glVertex2f (x+1+q->width,y+1-FONT_HEIGHT); + glEnd (); + + glEnable (GL_TEXTURE_2D); + } + + // Draw the texture + glColor3f (1,1,1); + glBindTexture( GL_TEXTURE_2D, q->texture_number ); + glBegin (GL_QUADS); + glTexCoord2f (0,0); + glVertex2f (x,y-FONT_HEIGHT); + glTexCoord2f (1,0); + glVertex2f (x+q->width,y-FONT_HEIGHT); + glTexCoord2f (1,1); + glVertex2f (x+q->width,y-FONT_HEIGHT-q->height); + glTexCoord2f (0,1); + glVertex2f (x,y-FONT_HEIGHT-q->height); + glEnd (); + + // draw the selection border + if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name)) + { + glLineWidth (3); + glColor3f (1,0,0); + glDisable (GL_TEXTURE_2D); + + glBegin (GL_LINE_LOOP); + glVertex2f (x-4,y-FONT_HEIGHT+4); + glVertex2f (x-4,y-FONT_HEIGHT-q->height-4); + glVertex2f (x+4+q->width,y-FONT_HEIGHT-q->height-4); + glVertex2f (x+4+q->width,y-FONT_HEIGHT+4); + glEnd (); + + glEnable (GL_TEXTURE_2D); + glLineWidth (1); + } + + // draw the texture name + glColor3f (0,0,0); + glRasterPos2f (x, y-FONT_HEIGHT+2); + + // don't draw the directory name + for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++) + ; + if (!*name) + name = q->name; + else + name++; + glCallLists (strlen(name), GL_UNSIGNED_BYTE, name); + } + } + + // reset the current texture + glBindTexture( GL_TEXTURE_2D, 0 ); + glFinish(); +} + +/* +============ +WTexWndProc +============ +*/ +LONG WINAPI WTex_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + int xPos, yPos; + RECT rect; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_CREATE: + s_hdcTexture = GetDC(hWnd); + QEW_SetupPixelFormat(s_hdcTexture, false); + + if ( ( s_hglrcTexture = wglCreateContext( s_hdcTexture ) ) == 0 ) + Error( "wglCreateContext in WTex_WndProc failed" ); + + if (!wglMakeCurrent( s_hdcTexture, s_hglrcTexture )) + Error ("wglMakeCurrent in WTex_WndProc failed"); + + if (!wglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) ) + Error( "wglShareLists in WTex_WndProc failed" ); + + return 0; + + case WM_DESTROY: + wglMakeCurrent( NULL, NULL ); + wglDeleteContext( s_hglrcTexture ); + ReleaseDC( hWnd, s_hdcTexture ); + return 0; + + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hWnd, &ps); + + if ( !wglMakeCurrent( s_hdcTexture, s_hglrcTexture ) ) + Error ("wglMakeCurrent failed"); + Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top); + SwapBuffers(s_hdcTexture); + + EndPaint(hWnd, &ps); + } + return 0; + + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + SetCapture( g_qeglobals.d_hwndTexture ); + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + + Texture_MouseDown (xPos, yPos, wParam); + return 0; + + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONUP: + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + + Texture_MouseUp (xPos, yPos, wParam); + if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); + return 0; + + case WM_MOUSEMOVE: + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + + Texture_MouseMoved (xPos, yPos, wParam); + return 0; + } + + return DefWindowProc (hWnd, uMsg, wParam, lParam); +} + + + +/* +================== +CreateTextureWindow + +We need to create a seperate window for the textures +in the inspector window, because we can't share +gl and gdi drawing in a single window +================== +*/ +#define TEXTURE_WINDOW_CLASS "QTEX" +HWND CreateTextureWindow (void) +{ + WNDCLASS wc; + HWND hwnd; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WTex_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_qeglobals.d_hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = TEXTURE_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Error ("WCam_Register: failed"); + + hwnd = CreateWindow (TEXTURE_WINDOW_CLASS , + "Texture View", + WS_BORDER|WS_CHILD|WS_VISIBLE, + 20, + 20, + 64, + 64, // size + + g_qeglobals.d_hwndEntity, // parent window + 0, // no menu + g_qeglobals.d_hInstance, + 0); + if (!hwnd) + Error ("Couldn't create texturewindow"); + + return hwnd; +} + +/* +================== +Texture_Flush +================== +*/ +void Texture_Flush (void) +{ +} + + +/* +================== +Texture_Init +================== +*/ +void Texture_Init (void) +{ + char name[1024]; + byte *pal; + + // load the palette + sprintf (name, "%s/pics/colormap.pcx", + ValueForKey (g_qeglobals.d_project_entity, "basepath")); + Load256Image (name, NULL, &pal, NULL, NULL); + if (!pal) + Error ("Couldn't load %s", name); + Texture_InitPalette (pal); + free (pal); + + // create the fallback texture + Texture_MakeNotexture (); + + g_qeglobals.d_qtextures = NULL; +} + diff --git a/tools/quake2/extra/qe4/textures.h b/tools/quake2/extra/qe4/textures.h new file mode 100644 index 00000000..e85353fc --- /dev/null +++ b/tools/quake2/extra/qe4/textures.h @@ -0,0 +1,70 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +typedef struct +{ + char name[32]; + float shift[2]; + float rotate; + float scale[2]; + int contents; + int flags; + int value; +} texdef_t; + + +typedef struct +{ + int width, height; + int originy; + texdef_t texdef; +} texturewin_t; + +typedef struct qtexture_s +{ + struct qtexture_s *next; + char name[64]; // includes partial directory and extension + int width, height; + int contents; + int flags; + int value; + int texture_number; // gl bind number + vec3_t color; // for flat shade mode + qboolean inuse; // true = is present on the level +} qtexture_t; + + +// a texturename of the form (0 0 0) will +// create a solid color texture + +void Texture_Init (void); +void Texture_Flush (void); +void Texture_ClearInuse (void); +void Texture_ShowInuse (void); +void Texture_ShowDirectory (int menunum); + +qtexture_t *Texture_ForName (char *name); + +void Texture_Init (void); +void Texture_SetTexture (texdef_t *texdef); + +void Texture_SetMode(int iMenu); // GL_TEXTURE_NEAREST, etc.. diff --git a/tools/quake2/extra/qe4/toolbar1.bmp b/tools/quake2/extra/qe4/toolbar1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f942898ba036cc606153f137daa2503e2cc489d7 GIT binary patch literal 1918 zcmb7^L2lbX3`JQZfCz7L1tF`Rqx;@Pt17Evc9~;z?Nj(jy@C7wpONIKfebSq{^4-Q zPf}8T{QNzHo4n-^(|h|5!wAVKB*GHFG^{EX3HvZy=(r8%-UUgoUA1@N!^&J!b;Q+W^u zl1!3a4B>|39BO#?nmx2l&}PJ|l;nf)o>!Ig02sSy;bnyQYs`}yj>{i6EcY`4Tbl?K zuoG|47UV2ZTHW(P&Bd5!#sFR}@diFCye52UifS)vz++x=o6;(E+8op*s|+-p;F*Rw zBSx}dH+xH*YnJkN^u>i&4)seVE=TFx^L=0E>|Rxc8crb%gTYp^VA@)F_jP>Y4T9k1 zGQ6oz2KVwEC9j(bEJ@KMRl`cIhCv-k7ED_kFS#rmZgYmE{reEFo8EX^R03q?hiV@% z4a2+4cg3E+&57zX6J$YA^`bOi9Jm^#_BL#zgbMZhESD_sOxV-1@wU)z7t?&5P31`z HI`RJlI#}rz literal 0 HcmV?d00001 diff --git a/tools/quake2/extra/qe4/vertsel.c b/tools/quake2/extra/qe4/vertsel.c new file mode 100644 index 00000000..613824f7 --- /dev/null +++ b/tools/quake2/extra/qe4/vertsel.c @@ -0,0 +1,245 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +int FindPoint (vec3_t point) +{ + int i, j; + + for (i=0 ; i 0.1) + break; + if (j == 3) + return i; + } + + VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]); + g_qeglobals.d_numpoints++; + + return g_qeglobals.d_numpoints-1; +} + +int FindEdge (int p1, int p2, face_t *f) +{ + int i; + + for (i=0 ; inumpoints ; i++) + pnum[i] = FindPoint (w->points[i]); + for (i=0 ; inumpoints ; i++) + FindEdge (pnum[i], pnum[(i+1)%w->numpoints], f); + + free (w); +} + +void SetupVertexSelection (void) +{ + face_t *f; + brush_t *b; + + g_qeglobals.d_numpoints = 0; + g_qeglobals.d_numedges = 0; + if (!QE_SingleBrush()) + return; + b = selected_brushes.next; + for (f=b->brush_faces ; f ; f=f->next) + MakeFace (f); + + Sys_UpdateWindows (W_ALL); +} + + +void SelectFaceEdge (face_t *f, int p1, int p2) +{ + winding_t *w; + int i, j, k; + int pnum[128]; + + w = MakeFaceWinding (selected_brushes.next, f); + if (!w) + return; + for (i=0 ; inumpoints ; i++) + pnum[i] = FindPoint (w->points[i]); + for (i=0 ; inumpoints ; i++) + if (pnum[i] == p1 && pnum[(i+1)%w->numpoints] == p2) + { + VectorCopy (g_qeglobals.d_points[pnum[i]], f->planepts[0]); + VectorCopy (g_qeglobals.d_points[pnum[(i+1)%w->numpoints]], f->planepts[1]); + VectorCopy (g_qeglobals.d_points[pnum[(i+2)%w->numpoints]], f->planepts[2]); + for (j=0 ; j<3 ; j++) + { + for (k=0 ; k<3 ; k++) + { + f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + } + } + + AddPlanept (f->planepts[0]); + AddPlanept (f->planepts[1]); + break; + } + + if (i == w->numpoints) + Sys_Printf ("SelectFaceEdge: failed\n"); + free (w); +} + +void SelectVertex (int p1) +{ + brush_t *b; + winding_t *w; + int i, j, k; + face_t *f; + + b = selected_brushes.next; + for (f=b->brush_faces ; f ; f=f->next) + { + w = MakeFaceWinding (b, f); + if (!w) + continue; + for (i=0 ; inumpoints ; i++) + { + if (FindPoint (w->points[i]) == p1) + { + VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]); + VectorCopy (w->points[i], f->planepts[1]); + VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]); + for (j=0 ; j<3 ; j++) + { + for (k=0 ; k<3 ; k++) + { + f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + } + } + + AddPlanept (f->planepts[1]); + break; + } + } + free (w); + } +} + +void SelectEdgeByRay (vec3_t org, vec3_t dir) +{ + int i, j, besti; + float d, bestd; + vec3_t mid, temp; + pedge_t *e; + + // find the edge closest to the ray + besti = -1; + bestd = 8; + + for (i=0 ; if1, e->p1, e->p2); + SelectFaceEdge (e->f2, e->p2, e->p1); +} + +void SelectVertexByRay (vec3_t org, vec3_t dir) +{ + int i, besti; + float d, bestd; + vec3_t temp; + + // find the point closest to the ray + besti = -1; + bestd = 8; + + for (i=0 ; inext; + if (e == &entities) + { + Sys_Status ("No such entity.", 0); + return; + } + } + } + + b = e->brushes.onext; + if (b == &e->brushes) + { + Sys_Status ("No such brush.", 0); + return; + } + while (brushnum--) + { + b=b->onext; + if (b == &e->brushes) + { + Sys_Status ("No such brush.", 0); + return; + } + } + + Brush_RemoveFromList (b); + Brush_AddToList (b, &selected_brushes); + + + Sys_UpdateWindows (W_ALL); + for (i=0 ; i<3 ; i++) + g_qeglobals.d_xy.origin[i] = (b->mins[i] + b->maxs[i])/2; + + Sys_Status ("Selected.", 0); +} + +/* +================= +GetSelectionIndex +================= +*/ +void GetSelectionIndex (int *ent, int *brush) +{ + brush_t *b, *b2; + entity_t *entity; + + *ent = *brush = 0; + + b = selected_brushes.next; + if (b == &selected_brushes) + return; + + // find entity + if (b->owner != world_entity) + { + (*ent)++; + for (entity = entities.next ; entity != &entities + ; entity=entity->next, (*ent)++) + ; + } + + // find brush + for (b2=b->owner->brushes.onext + ; b2 != b && b2 != &b->owner->brushes + ; b2=b2->onext, (*brush)++) + ; +} + +BOOL CALLBACK FindBrushDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char entstr[256]; + char brushstr[256]; + HWND h; + int ent, brush; + + switch (uMsg) + { + case WM_INITDIALOG: + // set entity and brush number + GetSelectionIndex (&ent, &brush); + sprintf (entstr, "%i", ent); + sprintf (brushstr, "%i", brush); + SetWindowText(GetDlgItem(hwndDlg, IDC_FIND_ENTITY), entstr); + SetWindowText(GetDlgItem(hwndDlg, IDC_FIND_BRUSH), brushstr); + + h = GetDlgItem(hwndDlg, IDC_FIND_ENTITY); + SetFocus (h); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_FIND_ENTITY), entstr, 255); + GetWindowText(GetDlgItem(hwndDlg, IDC_FIND_BRUSH), brushstr, 255); + SelectBrush (atoi(entstr), atoi(brushstr)); + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + return FALSE; +} + + + +void DoFind(void) +{ + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_FINDBRUSH, g_qeglobals.d_hwndMain, FindBrushDlgProc); +} + +/* +=================================================== + + ARBITRARY ROTATE + +=================================================== +*/ + + +BOOL CALLBACK RotateDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char str[256]; + HWND h; + float v; + + switch (uMsg) + { + case WM_INITDIALOG: + h = GetDlgItem(hwndDlg, IDC_FIND_ENTITY); + SetFocus (h); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_ROTX), str, 255); + v = atof(str); + if (v) + Select_RotateAxis (0, v); + + GetWindowText(GetDlgItem(hwndDlg, IDC_ROTY), str, 255); + v = atof(str); + if (v) + Select_RotateAxis (1, v); + + GetWindowText(GetDlgItem(hwndDlg, IDC_ROTZ), str, 255); + v = atof(str); + if (v) + Select_RotateAxis (2, v); + + EndDialog(hwndDlg, 1); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + } + + return FALSE; +} + + + +void DoRotate(void) +{ + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ROTATE, g_qeglobals.d_hwndMain, RotateDlgProc); +} + +/* +=================================================== + + ARBITRARY SIDES + +=================================================== +*/ + + +BOOL CALLBACK SidesDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + char str[256]; + HWND h; + + switch (uMsg) + { + case WM_INITDIALOG: + h = GetDlgItem(hwndDlg, IDC_FIND_ENTITY); + SetFocus (h); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + + case IDOK: + GetWindowText(GetDlgItem(hwndDlg, IDC_SIDES), str, 255); + Brush_MakeSided (atoi(str)); + + EndDialog(hwndDlg, 1); + break; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + break; + } + default: + return FALSE; + } +} + + + +void DoSides(void) +{ + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_SIDES, g_qeglobals.d_hwndMain, SidesDlgProc); +} + +//====================================================================== + +/* +=================== +DoAbout +=================== +*/ +BOOL CALLBACK AboutDlgProc( HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + char renderer[1024]; + char version[1024]; + char vendor[1024]; + char extensions[4096]; + + sprintf( renderer, "Renderer:\t%s", glGetString( GL_RENDERER ) ); + sprintf( version, "Version:\t\t%s", glGetString( GL_VERSION ) ); + sprintf( vendor, "Vendor:\t\t%s", glGetString( GL_VENDOR ) ); + sprintf( extensions, "\n%s", glGetString( GL_EXTENSIONS ) ); + + SetWindowText( GetDlgItem( hwndDlg, IDC_ABOUT_GLRENDERER ), renderer ); + SetWindowText( GetDlgItem( hwndDlg, IDC_ABOUT_GLVERSION ), version ); + SetWindowText( GetDlgItem( hwndDlg, IDC_ABOUT_GLVENDOR ), vendor ); + SetWindowText( GetDlgItem( hwndDlg, IDC_ABOUT_GLEXTENSIONS ), extensions ); + } + return TRUE; + + case WM_CLOSE: + EndDialog( hwndDlg, 1 ); + return TRUE; + + case WM_COMMAND: + if ( LOWORD( wParam ) == IDOK ) + EndDialog(hwndDlg, 1); + return TRUE; + } + return FALSE; +} + +void DoAbout(void) +{ + DialogBox( g_qeglobals.d_hInstance, ( char * ) IDD_ABOUT, g_qeglobals.d_hwndMain, AboutDlgProc ); +} + + +/* +=================================================== + + SURFACE INSPECTOR + +=================================================== +*/ + +texdef_t g_old_texdef; +HWND g_surfwin; +qboolean g_changed_surface; + +int g_checkboxes[64] = { + IDC_CHECK1, IDC_CHECK2, IDC_CHECK3, IDC_CHECK4, + IDC_CHECK5, IDC_CHECK6, IDC_CHECK7, IDC_CHECK8, + IDC_CHECK9, IDC_CHECK10, IDC_CHECK11, IDC_CHECK12, + IDC_CHECK13, IDC_CHECK14, IDC_CHECK15, IDC_CHECK16, + IDC_CHECK17, IDC_CHECK18, IDC_CHECK19, IDC_CHECK20, + IDC_CHECK21, IDC_CHECK22, IDC_CHECK23, IDC_CHECK24, + IDC_CHECK25, IDC_CHECK26, IDC_CHECK27, IDC_CHECK28, + IDC_CHECK29, IDC_CHECK30, IDC_CHECK31, IDC_CHECK32, + + IDC_CHECK33, IDC_CHECK34, IDC_CHECK35, IDC_CHECK36, + IDC_CHECK37, IDC_CHECK38, IDC_CHECK39, IDC_CHECK40, + IDC_CHECK41, IDC_CHECK42, IDC_CHECK43, IDC_CHECK44, + IDC_CHECK45, IDC_CHECK46, IDC_CHECK47, IDC_CHECK48, + IDC_CHECK49, IDC_CHECK50, IDC_CHECK51, IDC_CHECK52, + IDC_CHECK53, IDC_CHECK54, IDC_CHECK55, IDC_CHECK56, + IDC_CHECK57, IDC_CHECK58, IDC_CHECK59, IDC_CHECK60, + IDC_CHECK61, IDC_CHECK62, IDC_CHECK63, IDC_CHECK64 + }; + +/* +============== +SetTexMods + +Set the fields to the current texdef +=============== +*/ +void SetTexMods(void) +{ + char sz[128]; + texdef_t *pt; + int i; + + pt = &g_qeglobals.d_texturewin.texdef; + + SendMessage (g_surfwin, WM_SETREDRAW, 0, 0); + + SetWindowText(GetDlgItem(g_surfwin, IDC_TEXTURE), pt->name); + + sprintf(sz, "%d", (int)pt->shift[0]); + SetWindowText(GetDlgItem(g_surfwin, IDC_HSHIFT), sz); + + sprintf(sz, "%d", (int)pt->shift[1]); + SetWindowText(GetDlgItem(g_surfwin, IDC_VSHIFT), sz); + + sprintf(sz, "%4.2f", pt->scale[0]); + SetWindowText(GetDlgItem(g_surfwin, IDC_HSCALE), sz); + + sprintf(sz, "%4.2f", pt->scale[1]); + SetWindowText(GetDlgItem(g_surfwin, IDC_VSCALE), sz); + + sprintf(sz, "%d", (int)pt->rotate); + SetWindowText(GetDlgItem(g_surfwin, IDC_ROTATE), sz); + + sprintf(sz, "%d", (int)pt->value); + SetWindowText(GetDlgItem(g_surfwin, IDC_VALUE), sz); + + for (i=0 ; i<32 ; i++) + SendMessage(GetDlgItem(g_surfwin, g_checkboxes[i]), BM_SETCHECK, !!(pt->flags&(1<contents&(1<name, sz, sizeof(pt->name)-1); + if (pt->name[0] <= ' ') + { + strcpy (pt->name, "none"); + SetWindowText(GetDlgItem(g_surfwin, IDC_TEXTURE), pt->name); + } + + GetWindowText (GetDlgItem(g_surfwin, IDC_HSHIFT), sz, 127); + pt->shift[0] = atof(sz); + + GetWindowText (GetDlgItem(g_surfwin, IDC_VSHIFT), sz, 127); + pt->shift[1] = atof(sz); + + GetWindowText(GetDlgItem(g_surfwin, IDC_HSCALE), sz, 127); + pt->scale[0] = atof(sz); + + GetWindowText(GetDlgItem(g_surfwin, IDC_VSCALE), sz, 127); + pt->scale[1] = atof(sz); + + GetWindowText(GetDlgItem(g_surfwin, IDC_ROTATE), sz, 127); + pt->rotate = atof(sz); + + GetWindowText(GetDlgItem(g_surfwin, IDC_VALUE), sz, 127); + pt->value = atof(sz); + + pt->flags = 0; + for (i=0 ; i<32 ; i++) + { + b = SendMessage(GetDlgItem(g_surfwin, g_checkboxes[i]), BM_GETCHECK, 0, 0); + if (b != 1 && b != 0) + continue; + pt->flags |= b<contents = 0; + for (i=0 ; i<32 ; i++) + { + b = SendMessage(GetDlgItem(g_surfwin, g_checkboxes[32+i]), BM_GETCHECK, 0, 0); + if (b != 1 && b != 0) + continue; + pt->contents |= b<rotate += 45; + else + pt->rotate -= 45; + + if (pt->rotate < 0) + pt->rotate += 360; + + if (pt->rotate >= 360) + pt->rotate -= 360; + } + + else if (hwnd == GetDlgItem(g_surfwin, IDC_HSCALEA)) + { + if (nScrollCode == SB_LINEDOWN) + pt->scale[0] -= 0.1; + else + pt->scale[0] += 0.1; + } + + else if (hwnd == GetDlgItem(g_surfwin, IDC_VSCALEA)) + { + if (nScrollCode == SB_LINEUP) + pt->scale[1] += 0.1; + else + pt->scale[1] -= 0.1; + } + + else if (hwnd == GetDlgItem(g_surfwin, IDC_HSHIFTA)) + { + if (nScrollCode == SB_LINEDOWN) + pt->shift[0] -= 8; + else + pt->shift[0] += 8; + } + + else if (hwnd == GetDlgItem(g_surfwin, IDC_VSHIFTA)) + { + if (nScrollCode == SB_LINEUP) + pt->shift[1] += 8; + else + pt->shift[1] -= 8; + } + + SetTexMods(); + g_changed_surface = true; + Select_SetTexture(pt); +} + + + +BOOL CALLBACK SurfaceDlgProc ( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + g_surfwin = hwndDlg; + SetTexMods (); + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + + case IDOK: + GetTexMods (); + EndDialog(hwndDlg, 1); + break; + + case IDAPPLY: + GetTexMods (); + InvalidateRect(g_qeglobals.d_hwndCamera, NULL, false); + UpdateWindow (g_qeglobals.d_hwndCamera); + break; + + case IDCANCEL: + g_qeglobals.d_texturewin.texdef = g_old_texdef; + if (g_changed_surface) + Select_SetTexture(&g_qeglobals.d_texturewin.texdef); + EndDialog(hwndDlg, 0); + break; + } + break; + + case WM_HSCROLL: + case WM_VSCROLL: + UpdateSpinners(uMsg, wParam, lParam); + InvalidateRect(g_qeglobals.d_hwndCamera, NULL, false); + UpdateWindow (g_qeglobals.d_hwndCamera); + return 0; + + default: + return FALSE; + } +} + + + +void DoSurface (void) +{ + // save current state for cancel + g_old_texdef = g_qeglobals.d_texturewin.texdef; + g_changed_surface = false; + + DialogBox(g_qeglobals.d_hInstance, (char *)IDD_SURFACE, g_qeglobals.d_hwndMain, SurfaceDlgProc); +} + diff --git a/tools/quake2/extra/qe4/win_ent.c b/tools/quake2/extra/qe4/win_ent.c new file mode 100644 index 00000000..74fa9589 --- /dev/null +++ b/tools/quake2/extra/qe4/win_ent.c @@ -0,0 +1,1137 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" +#include "entityw.h" + +int rgIds[EntLast] = { + IDC_E_LIST, + IDC_E_COMMENT, + IDC_CHECK1, + IDC_CHECK2, + IDC_CHECK3, + IDC_CHECK4, + IDC_CHECK5, + IDC_CHECK6, + IDC_CHECK7, + IDC_CHECK8, + IDC_CHECK9, + IDC_CHECK10, + IDC_CHECK11, + IDC_CHECK12, + IDC_E_PROPS, + IDC_E_0, + IDC_E_45, + IDC_E_90, + IDC_E_135, + IDC_E_180, + IDC_E_225, + IDC_E_270, + IDC_E_315, + IDC_E_UP, + IDC_E_DOWN, + IDC_E_DELPROP, + + IDC_STATIC_KEY, + IDC_E_KEY_FIELD, + IDC_STATIC_VALUE, + IDC_E_VALUE_FIELD, + + IDC_E_COLOR +}; + +HWND hwndEnt[EntLast]; + +int inspector_mode; // W_TEXTURE, W_ENTITY, or W_CONSOLE + +qboolean multiple_entities; + +entity_t *edit_entity; + +HWND CreateTextureWindow (void); + +BOOL CALLBACK EntityWndProc( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam); // second message parameter + +void SizeEntityDlg(int iWidth, int iHeight); +void AddProp(void); +void GetTexMods(void); + + +LRESULT (CALLBACK* OldFieldWindowProc) (HWND, UINT, WPARAM, LPARAM); +LRESULT (CALLBACK* OldEntityListWindowProc) (HWND, UINT, WPARAM, LPARAM); + +/* +========================= +FieldWndProc + +Just to handle tab and enter... +========================= +*/ +BOOL CALLBACK FieldWndProc( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_CHAR: + if (LOWORD(wParam) == VK_TAB) + return FALSE; + if (LOWORD(wParam) == VK_RETURN) + return FALSE; + if (LOWORD(wParam) == VK_ESCAPE) + { + SetFocus (g_qeglobals.d_hwndCamera); + return FALSE; + } + break; + + case WM_KEYDOWN: + if (LOWORD(wParam) == VK_TAB) + { + if (hwnd == hwndEnt[EntKeyField]) + { + SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)""); + SetFocus (hwndEnt[EntValueField]); + } + else + SetFocus (hwndEnt[EntKeyField]); + } + if (LOWORD(wParam) == VK_RETURN) + { + if (hwnd == hwndEnt[EntKeyField]) + { + SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)""); + SetFocus (hwndEnt[EntValueField]); + } + else + { + AddProp (); + SetFocus (g_qeglobals.d_hwndCamera); + } + } + break; +// case WM_NCHITTEST: + case WM_LBUTTONDOWN: + SetFocus (hwnd); + break; + } + return CallWindowProc (OldFieldWindowProc, hwnd, uMsg, wParam, lParam); +} + + +/* +========================= +EntityListWndProc + +Just to handle enter... +========================= +*/ +BOOL CALLBACK EntityListWndProc( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_KEYDOWN: + if (LOWORD(wParam) == VK_RETURN) + { + SendMessage ( g_qeglobals.d_hwndEntity, + WM_COMMAND, + (LBN_DBLCLK<<16) + IDC_E_LIST, + 0 ); + return 0; + } + break; + } + return CallWindowProc (OldEntityListWindowProc, hwnd, uMsg, wParam, lParam); +} + + +/* +================ +GetEntityControls + +Finds the controls from the dialog and +moves them to the window +================ +*/ +void GetEntityControls(HWND ghwndEntity) +{ + int i; + + for (i = 0; i < EntLast; i++) + { + if (i == EntList || i == EntProps || i == EntComment) + continue; + if (i == EntKeyField || i == EntValueField) + continue; + hwndEnt[i] = GetDlgItem(ghwndEntity, rgIds[i]); + if (hwndEnt[i]) + SetParent (hwndEnt[i], g_qeglobals.d_hwndEntity ); + } + + + // SetParent apears to not modify some internal state + // on listboxes, so create it from scratch... + + hwndEnt[EntList] = CreateWindow ("listbox", NULL, + LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT + | WS_VSCROLL | WS_CHILD | WS_VISIBLE, + 5, 5, 180, 99, + g_qeglobals.d_hwndEntity, + (void *)IDC_E_LIST, + g_qeglobals.d_hInstance, + NULL); + if (!hwndEnt[EntList]) + Error ("CreateWindow failed"); + + hwndEnt[EntProps] = CreateWindow ("listbox", NULL, + LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS + | WS_VSCROLL | WS_CHILD | WS_VISIBLE, + 5, 100, 180, 99, + g_qeglobals.d_hwndEntity, + (void *)IDC_E_PROPS, + g_qeglobals.d_hInstance, + NULL); + if (!hwndEnt[EntProps]) + Error ("CreateWindow failed"); + + hwndEnt[EntComment] = CreateWindow ("edit", NULL, + ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER, + 5, 100, 180, 99, + g_qeglobals.d_hwndEntity, + (void *)IDC_E_COMMENT, + g_qeglobals.d_hInstance, + NULL); + if (!hwndEnt[EntComment]) + Error ("CreateWindow failed"); + + hwndEnt[EntKeyField] = CreateWindow ("edit", NULL, + WS_CHILD | WS_VISIBLE | WS_BORDER, + 5, 100, 180, 99, + g_qeglobals.d_hwndEntity, + (void *)IDC_E_KEY_FIELD, + g_qeglobals.d_hInstance, + NULL); + if (!hwndEnt[EntKeyField]) + Error ("CreateWindow failed"); + + hwndEnt[EntValueField] = CreateWindow ("edit", NULL, + WS_CHILD | WS_VISIBLE | WS_BORDER, + 5, 100, 180, 99, + g_qeglobals.d_hwndEntity, + (void *)IDC_E_VALUE_FIELD, + g_qeglobals.d_hInstance, + NULL); + if (!hwndEnt[EntValueField]) + Error ("CreateWindow failed"); + + g_qeglobals.d_hwndEdit = CreateWindow ("edit", NULL, + ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER, + 5, 100, 180, 99, + g_qeglobals.d_hwndEntity, + (void *)IDC_E_STATUS, + g_qeglobals.d_hInstance, + NULL); + if (!g_qeglobals.d_hwndEdit) + Error ("CreateWindow failed"); + + g_qeglobals.d_hwndTexture = CreateTextureWindow (); + +#if 0 + for (i=0 ; i<12 ; i++) + { + hwndEnt[EntCheck1 + i] = CreateWindow ("button", NULL, + BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE, + 5, 100, 180, 99, + entwindow, + (void *)IDC_E_STATUS, + main_instance, + NULL); + if (!hwndEnt[EntCheck1 + i]) + Error ("CreateWindow failed"); + } +#endif +} + + + +/* +=============================================================== + +ENTITY WINDOW + +=============================================================== +*/ + + +void FillClassList (void) +{ + eclass_t *pec; + int iIndex; + + SendMessage(hwndEnt[EntList], LB_RESETCONTENT, 0 , 0); + + for (pec = eclass ; pec ; pec = pec->next) + { + iIndex = SendMessage(hwndEnt[EntList], LB_ADDSTRING, 0 , (LPARAM)pec->name); + SendMessage(hwndEnt[EntList], LB_SETITEMDATA, iIndex, (LPARAM)pec); + } + +} + + +/* +============== +WEnt_Create +============== +*/ +void WEnt_Create (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)EntityWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = GetStockObject (LTGRAY_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = ENT_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Error ("RegisterClass: failed"); + + g_qeglobals.d_hwndEntity = CreateWindow (ENT_WINDOW_CLASS , + "Entity", + QE3_STYLE , + 20, + 20, + 100, + 480, // size + + g_qeglobals.d_hwndMain, // parent + 0, // no menu + hInstance, + NULL); + + if (!g_qeglobals.d_hwndEntity ) + Error ("Couldn't create Entity window"); +} + +/* +============== +CreateEntityWindow +============== +*/ +BOOL CreateEntityWindow(HINSTANCE hInstance) +{ + HWND hwndEntityPalette; + + inspector_mode = W_ENTITY; + + WEnt_Create (hInstance); + + hwndEntityPalette = CreateDialog(hInstance, (char *)IDD_ENTITY, g_qeglobals.d_hwndMain, (DLGPROC)NULL); + if (!hwndEntityPalette) + Error ("CreateDialog failed"); + + GetEntityControls (hwndEntityPalette); + DestroyWindow (hwndEntityPalette); + + OldFieldWindowProc = (void *)GetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC); + SetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC, (long)FieldWndProc); + SetWindowLong (hwndEnt[EntValueField], GWL_WNDPROC, (long)FieldWndProc); + + OldEntityListWindowProc = (void *)GetWindowLong (hwndEnt[EntList], GWL_WNDPROC); + SetWindowLong (hwndEnt[EntList], GWL_WNDPROC, (long)EntityListWndProc); + + FillClassList (); + + LoadWindowState(g_qeglobals.d_hwndEntity, "EntityWindow"); + + ShowWindow (g_qeglobals.d_hwndEntity, SW_SHOW); + SetInspectorMode (W_CONSOLE); + + return TRUE; +} + +/* +============== +SetInspectorMode +============== +*/ +void SetInspectorMode(int iType) +{ + RECT rc; + HMENU hMenu = GetMenu( g_qeglobals.d_hwndMain ); + + // Is the caller asking us to cycle to the next window? + + if (iType == -1) + { + if (inspector_mode == W_ENTITY) + iType = W_TEXTURE; + else if (inspector_mode == W_TEXTURE) + iType = W_CONSOLE; + else + iType = W_ENTITY; + } + + inspector_mode = iType; + switch(iType) + { + + case W_ENTITY: + SetWindowText(g_qeglobals.d_hwndEntity, "Entity"); + EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_ENABLED | MF_BYCOMMAND ); + break; + + case W_TEXTURE: +// title is set by textures.c SetWindowText(g_qeglobals.d_hwndEntity, "Textures"); + EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ); + break; + + case W_CONSOLE: + SetWindowText(g_qeglobals.d_hwndEntity, "Console"); + EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ); + break; + + default: + break; + } + + GetWindowRect (g_qeglobals.d_hwndEntity, &rc); + SizeEntityDlg( rc.right - rc.left - 8, rc.bottom - rc.top - 32); + + RedrawWindow (g_qeglobals.d_hwndEntity, NULL, NULL, RDW_ERASE | RDW_INVALIDATE + | RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN); + +// InvalidateRect(entwindow, NULL, true); +// ShowWindow (entwindow, SW_SHOW); +// UpdateWindow (entwindow); + + SetWindowPos( g_qeglobals.d_hwndEntity, + HWND_TOP, + rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOSIZE | SWP_NOMOVE ); +} + + + + + +// SetKeyValuePairs +// +// Reset the key/value (aka property) listbox and fill it with the +// k/v pairs from the entity being edited. +// + +void SetKeyValuePairs (void) +{ + epair_t *pep; + RECT rc; + char sz[4096]; + + if (edit_entity == NULL) + return; + + // set key/value pair list + + GetWindowRect(hwndEnt[EntProps], &rc); + SendMessage(hwndEnt[EntProps], LB_SETCOLUMNWIDTH, (rc.right - rc.left)/2, 0); + SendMessage(hwndEnt[EntProps], LB_RESETCONTENT, 0, 0); + + // Walk through list and add pairs + + for (pep = edit_entity->epairs ; pep ; pep = pep->next) + { + // if the key is less than 8 chars, add a tab for alignment + if (strlen(pep->key) > 8) + sprintf (sz, "%s\t%s", pep->key, pep->value); + else + sprintf (sz, "%s\t\t%s", pep->key, pep->value); + SendMessage(hwndEnt[EntProps], LB_ADDSTRING, 0, (LPARAM)sz); + } + +} + +// SetSpawnFlags +// +// Update the checkboxes to reflect the flag state of the entity +// +void SetSpawnFlags(void) +{ + int f; + int i; + int v; + + f = atoi(ValueForKey (edit_entity, "spawnflags")); + for (i=0 ; i<12 ; i++) + { + v = !!(f&(1<next) + SetKeyValue(b->owner, "spawnflags", sz); + } + else + SetKeyValue (edit_entity, "spawnflags", sz); + SetKeyValuePairs (); +} + +// UpdateSel +// +// Update the listbox, checkboxes and k/v pairs to reflect the new selection +// + +BOOL UpdateSel(int iIndex, eclass_t *pec) +{ + int i; + brush_t *b; + + if (selected_brushes.next == &selected_brushes) + { + edit_entity = world_entity; + multiple_entities = false; + } + else + { + edit_entity = selected_brushes.next->owner; + for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next) + { + if (b->owner != edit_entity) + { + multiple_entities = true; + break; + } + } + } + + if (iIndex != LB_ERR) + SendMessage(hwndEnt[EntList], LB_SETCURSEL, iIndex, 0); + + if (pec == NULL) + return TRUE; + + // Set up the description + + SendMessage(hwndEnt[EntComment], WM_SETTEXT, 0, + (LPARAM)TranslateString(pec->comments)); + + for (i=0 ; i<8 ; i++) + { + HWND hwnd = hwndEnt[EntCheck1+i]; + if (pec->flagnames[i] && pec->flagnames[i][0] != 0) + { + EnableWindow(hwnd, TRUE); + SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)pec->flagnames[i]); + } else { + + // disable check box + SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)" "); + EnableWindow(hwnd, FALSE); + } + } + + SetSpawnFlags(); + SetKeyValuePairs(); + return TRUE; +} + +BOOL UpdateEntitySel(eclass_t *pec) +{ + int iIndex; + + iIndex = (int)SendMessage(hwndEnt[EntList], LB_FINDSTRINGEXACT, + (WPARAM)-1, (LPARAM)pec->name); + + return UpdateSel(iIndex, pec); +} + +// CreateEntity +// +// Creates a new entity based on the currently selected brush and entity type. +// + +void CreateEntity(void) +{ + eclass_t *pecNew; + entity_t *petNew; + int i; + HWND hwnd; + char sz[1024]; + + // check to make sure we have a brush + + if (selected_brushes.next == &selected_brushes) + { + MessageBox(g_qeglobals.d_hwndMain, "You must have a selected brush to create an entity" + , "info", 0); + return; + } + + + // find out what type of entity we are trying to create + + hwnd = hwndEnt[EntList]; + + i = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0); + + if (i < 0) + { + MessageBox(g_qeglobals.d_hwndMain, "You must have a selected class to create an entity" + , "info", 0); + return; + } + + SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz); + + if (!stricmp(sz, "worldspawn")) + { + MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0); + return; + } + + pecNew = Eclass_ForName(sz, false); + + // create it + + petNew = Entity_Create(pecNew); + + if (petNew == NULL) + { + MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0); + return; + } + + if (selected_brushes.next == &selected_brushes) + edit_entity = world_entity; + else + edit_entity = selected_brushes.next->owner; + + SetKeyValuePairs(); + Select_Deselect (); + Select_Brush (edit_entity->brushes.onext); +} + + + +/* +=============== +AddProp + +=============== +*/ +void AddProp(void) +{ + char key[4096]; + char value[4096]; + + if (edit_entity == NULL) + return; + + // Get current selection text + + SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(key)-1, (LPARAM)key); + SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(value)-1, (LPARAM)value); + + if (multiple_entities) + { + brush_t *b; + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + SetKeyValue(b->owner, key, value); + } + else + SetKeyValue(edit_entity, key, value); + + // refresh the prop listbox + + SetKeyValuePairs(); +} + +/* +=============== +DelProp + +=============== +*/ +void DelProp(void) +{ + char sz[4096]; + + if (edit_entity == NULL) + return; + + // Get current selection text + + SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz)-1, (LPARAM)sz); + + if (multiple_entities) + { + brush_t *b; + + for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) + DeleteKey(b->owner, sz); + } + else + DeleteKey(edit_entity, sz); + + // refresh the prop listbox + + SetKeyValuePairs(); +} + +/* +=============== +EditProp + +=============== +*/ +void EditProp(void) +{ + int i; + HWND hwnd; + char sz[4096]; + char *val; + + if (edit_entity == NULL) + return; + + hwnd = hwndEnt[EntProps]; + + // Get current selection text + + i = SendMessage(hwnd, LB_GETCURSEL, 0, 0); + + if (i < 0) + return; + + SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz); + + // strip it down to the key name + + for(i=0;sz[i] != '\t';i++) + ; + + sz[i] = '\0'; + + val = sz + i + 1; + if (*val == '\t') + val++; + + SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)sz); + SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)val); +} + + +HDWP defer; +int col; +void MOVE(HWND e, int x, int y, int w, int h) +{ +// defer=DeferWindowPos(defer,e,HWND_TOP,col+(x),y,w,h,SWP_SHOWWINDOW); +// MoveWindow (e, col+x, y, w, h, FALSE); + SetWindowPos (e, HWND_TOP, col+x, y, w, h, + SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOZORDER); +} + + +/* +=============== +SizeEnitityDlg + +Positions all controls so that the active inspector +is displayed correctly and the inactive ones are +off the side +=============== +*/ +void SizeEntityDlg(int iWidth, int iHeight) +{ + int y, x, xCheck, yCheck; + int i, iRow; + int w, h; + + if (iWidth < 32 || iHeight < 32) + return; + + SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 0, 0); + + //========================================== + + // + // console + // + + if (inspector_mode == W_CONSOLE) + col = 0; + else + col = iWidth; + + MOVE(g_qeglobals.d_hwndEdit, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) ); + + //========================================== + + // + // texture controls + // + if (inspector_mode == W_TEXTURE) + col = 0; + else + col = iWidth; + + MOVE(g_qeglobals.d_hwndTexture, DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) ); + + //========================================== + + // + // entity controls + // + if (inspector_mode == W_ENTITY) + col = 0; + else + col = iWidth; + + + // top half includes the entity list (2/3) and the + // comments (1/3) - 2 gaps, above and below. + + y = iHeight/2; + y -= 2 * DlgYBorder; + y = y / 3; + w = iWidth - (2 * DlgXBorder); + MOVE(hwndEnt[EntList], DlgXBorder, DlgYBorder, w, 2 * y); + + MOVE(hwndEnt[EntComment], + DlgXBorder, 2 * DlgYBorder + 2 * y, + w, y - (2 * DlgYBorder)); + + // bottom half includes flags (fixed), k/v pairs, + // and buttons (fixed). + + // xCheck = width of a single check box + // yCheck = distance from top of one check to the next + + xCheck = (iWidth - (2 * DlgXBorder)) / 3; + yCheck = 20; + + x = DlgXBorder; + + for (iRow = 0; iRow <= 12; iRow += 4) + { + y = iHeight/2; + + for (i = 0; i < 4; i++) + { + MOVE(hwndEnt[EntCheck1 + i + iRow], + x, y, xCheck, yCheck); + y += yCheck; + } + + x += xCheck; + } + + // + // properties scroll box + // + y = iHeight/2 + 4 * yCheck; + + w = iWidth - (2 * DlgXBorder); + h = (iHeight - (yCheck * 5 + 2 * DlgYBorder) ) - y; + + MOVE(hwndEnt[EntProps], DlgXBorder, y, w, h); + + y += h + DlgYBorder; + + // + // key / value fields + // + w = iWidth-(DlgXBorder+45); + MOVE(hwndEnt[EntKeyLabel], DlgXBorder, y, 40, yCheck); + MOVE(hwndEnt[EntKeyField], DlgXBorder+40, y, w, yCheck); + y += yCheck; + + MOVE(hwndEnt[EntValueLabel], DlgXBorder, y, 40, yCheck); + MOVE(hwndEnt[EntValueField], DlgXBorder+40, y, w, yCheck); + y += yCheck; + + // + // angle check boxes + // + i = y; + x = DlgXBorder; + + xCheck = yCheck*2; + + MOVE(hwndEnt[EntDir135], x, y, xCheck, yCheck); + y += yCheck; + + MOVE(hwndEnt[EntDir180], x, y, xCheck, yCheck); + y += yCheck; + + MOVE(hwndEnt[EntDir225], x, y, xCheck, yCheck); + + y = i; + x += xCheck; + + + MOVE(hwndEnt[EntDir90], x, y, xCheck, yCheck); + y += yCheck; + y += yCheck; + + MOVE(hwndEnt[EntDir270], x, y, xCheck, yCheck); + + y = i; + x += xCheck; + + + MOVE(hwndEnt[EntDir45], x, y, xCheck, yCheck); + y += yCheck; + + MOVE(hwndEnt[EntDir0], x, y, xCheck, yCheck); + y += yCheck; + + MOVE(hwndEnt[EntDir315], x, y, xCheck, yCheck); + + y = i + yCheck/2; + x += xCheck + xCheck/2; + + + MOVE(hwndEnt[EntDirUp], x, y, xCheck, yCheck); + y += yCheck; + + MOVE(hwndEnt[EntDirDown], x, y, xCheck, yCheck); + + y = i; + x += 1.5 * xCheck; + + MOVE(hwndEnt[EntDelProp], x, y, xCheck*2, yCheck); + y += yCheck; + + SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 1, 0); +// InvalidateRect(entwindow, NULL, TRUE); +} + + +/* +========================= +EntityWndProc +========================= +*/ +BOOL CALLBACK EntityWndProc( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam) // second message parameter +{ + RECT rc; + + GetClientRect(hwndDlg, &rc); + + switch (uMsg) + { + case WM_GETMINMAXINFO: + { + LPMINMAXINFO lpmmi; + + lpmmi = (LPMINMAXINFO) lParam; + lpmmi->ptMinTrackSize.x = 320; + lpmmi->ptMinTrackSize.y = 500; + } + return 0; + + case WM_WINDOWPOSCHANGING: + { + LPWINDOWPOS lpwp; + lpwp = (LPWINDOWPOS) lParam; + + DefWindowProc (hwndDlg, uMsg, wParam, lParam); + + lpwp->flags |= SWP_NOCOPYBITS; + SizeEntityDlg(lpwp->cx-8, lpwp->cy-32); + return 0; + + } + return 0; + + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_E_DELPROP: + DelProp(); + SetFocus (g_qeglobals.d_hwndCamera); + break; + + case IDC_E_0: + SetKeyValue (edit_entity, "angle", "0"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_45: + SetKeyValue (edit_entity, "angle", "45"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_90: + SetKeyValue (edit_entity, "angle", "90"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_135: + SetKeyValue (edit_entity, "angle", "135"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_180: + SetKeyValue (edit_entity, "angle", "180"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_225: + SetKeyValue (edit_entity, "angle", "225"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_270: + SetKeyValue (edit_entity, "angle", "270"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_315: + SetKeyValue (edit_entity, "angle", "315"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_UP: + SetKeyValue (edit_entity, "angle", "-1"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + case IDC_E_DOWN: + SetKeyValue (edit_entity, "angle", "-2"); + SetFocus (g_qeglobals.d_hwndCamera); + SetKeyValuePairs (); + break; + + case IDC_CHECK1: + case IDC_CHECK2: + case IDC_CHECK3: + case IDC_CHECK4: + case IDC_CHECK5: + case IDC_CHECK6: + case IDC_CHECK7: + case IDC_CHECK8: + case IDC_CHECK9: + case IDC_CHECK10: + case IDC_CHECK11: + case IDC_CHECK12: + GetSpawnFlags(); + SetFocus (g_qeglobals.d_hwndCamera); + break; + + + case IDC_E_PROPS: + switch (HIWORD(wParam)) + { + case LBN_SELCHANGE: + + EditProp(); + return TRUE; + } + break; + + case IDC_E_LIST: + + switch (HIWORD(wParam)) { + + case LBN_SELCHANGE: + { + int iIndex; + eclass_t *pec; + + iIndex = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0); + pec = (eclass_t *)SendMessage(hwndEnt[EntList], LB_GETITEMDATA, + iIndex, 0); + + UpdateSel(iIndex, pec); + + return TRUE; + break; + } + + case LBN_DBLCLK: + CreateEntity (); + SetFocus (g_qeglobals.d_hwndCamera); + break; + } + break; + + + default: + return DefWindowProc( hwndDlg, uMsg, wParam, lParam ); + } + + return 0; + } + + return DefWindowProc (hwndDlg, uMsg, wParam, lParam); +} diff --git a/tools/quake2/extra/qe4/win_main.c b/tools/quake2/extra/qe4/win_main.c new file mode 100644 index 00000000..cde20bca --- /dev/null +++ b/tools/quake2/extra/qe4/win_main.c @@ -0,0 +1,1327 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" +#include +#include "mru.h" +#include "entityw.h" + +static HWND s_hwndToolbar; + +BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize); +BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize); + +static HWND CreateMyStatusWindow(HINSTANCE hInst); +static HWND CreateToolBar(HINSTANCE hinst); + +extern int WXY_Print( void ); + +/* +============================================================================== + + MENU + +============================================================================== +*/ + +void OpenDialog (void); +void SaveAsDialog (void); +qboolean ConfirmModified (void); +void Select_Ungroup (void); + +void QE_ExpandBspString (char *bspaction, char *out, char *mapname) +{ + char *in; + char src[1024]; + char rsh[1024]; + char base[256]; + + ExtractFileName (mapname, base); + sprintf (src, "%s/maps/%s", ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), base); + strcpy (rsh, ValueForKey(g_qeglobals.d_project_entity, "rshcmd")); + + in = ValueForKey( g_qeglobals.d_project_entity, bspaction ); + while (*in) + { + if (in[0] == '!') + { + strcpy (out, rsh); + out += strlen(rsh); + in++; + continue; + } + if (in[0] == '$') + { + strcpy (out, src); + out += strlen(src); + in++; + continue; + } + if (in[0] == '@') + { + *out++ = '"'; + in++; + continue; + } + *out++ = *in++; + } + *out = 0; +} + + + +void RunBsp (char *command) +{ + char sys[1024]; + char batpath[1024]; + char outputpath[1024]; + char temppath[512]; + char name[1024]; + FILE *hFile; + BOOL ret; + PROCESS_INFORMATION ProcessInformation; + STARTUPINFO startupinfo; + + SetInspectorMode (W_CONSOLE); + + if (bsp_process) + { + Sys_Printf ("BSP is still going...\n"); + return; + } + + GetTempPath(512, temppath); + sprintf (outputpath, "%sjunk.txt", temppath); + + strcpy (name, currentmap); + if (region_active) + { + Map_SaveFile (name, false); + StripExtension (name); + strcat (name, ".reg"); + } + + Map_SaveFile (name, region_active); + + + QE_ExpandBspString (command, sys, name); + + Sys_ClearPrintf (); + Sys_Printf ("======================================\nRunning bsp command...\n"); + Sys_Printf ("\n%s\n", sys); + + // + // write qe3bsp.bat + // + sprintf (batpath, "%sqe3bsp.bat", temppath); + hFile = fopen(batpath, "w"); + if (!hFile) + Error ("Can't write to %s", batpath); + fprintf (hFile, sys); + fclose (hFile); + + // + // write qe3bsp2.bat + // + sprintf (batpath, "%sqe3bsp2.bat", temppath); + hFile = fopen(batpath, "w"); + if (!hFile) + Error ("Can't write to %s", batpath); + fprintf (hFile, "%sqe3bsp.bat > %s", temppath, outputpath); + fclose (hFile); + + Pointfile_Delete (); + + GetStartupInfo (&startupinfo); + + ret = CreateProcess( + batpath, // pointer to name of executable module + NULL, // pointer to command line string + NULL, // pointer to process security attributes + NULL, // pointer to thread security attributes + FALSE, // handle inheritance flag + 0 /*DETACHED_PROCESS*/, // creation flags + NULL, // pointer to new environment block + NULL, // pointer to current directory name + &startupinfo, // pointer to STARTUPINFO + &ProcessInformation // pointer to PROCESS_INFORMATION + ); + + if (!ret) + Error ("CreateProcess failed"); + + bsp_process = ProcessInformation.hProcess; + + Sleep (100); // give the new process a chance to open it's window + + BringWindowToTop( g_qeglobals.d_hwndMain ); // pop us back on top + SetFocus (g_qeglobals.d_hwndCamera); +} + +/* +============= +DoColor + +============= +*/ +qboolean DoColor(int iIndex) +{ + CHOOSECOLOR cc; + static COLORREF custom[16]; + + cc.lStructSize = sizeof(cc); + cc.hwndOwner = g_qeglobals.d_hwndMain; + cc.hInstance = g_qeglobals.d_hInstance; + cc.rgbResult = + (int)(g_qeglobals.d_savedinfo.colors[iIndex][0]*255) + + (((int)(g_qeglobals.d_savedinfo.colors[iIndex][1]*255))<<8) + + (((int)(g_qeglobals.d_savedinfo.colors[iIndex][2]*255))<<16); + cc.lpCustColors = custom; + cc.Flags = CC_FULLOPEN|CC_RGBINIT; + //cc.lCustData; + //cc.lpfnHook; + //cc.lpTemplateName + + if (!ChooseColor(&cc)) + return false; + + g_qeglobals.d_savedinfo.colors[iIndex][0] = (cc.rgbResult&255)/255.0; + g_qeglobals.d_savedinfo.colors[iIndex][1] = ((cc.rgbResult>>8)&255)/255.0; + g_qeglobals.d_savedinfo.colors[iIndex][2] = ((cc.rgbResult>>16)&255)/255.0; + + /* + ** scale colors so that at least one component is at 1.0F + ** if this is meant to select an entity color + */ + if ( iIndex == COLOR_ENTITY ) + { + float largest = 0.0F; + + if ( g_qeglobals.d_savedinfo.colors[iIndex][0] > largest ) + largest = g_qeglobals.d_savedinfo.colors[iIndex][0]; + if ( g_qeglobals.d_savedinfo.colors[iIndex][1] > largest ) + largest = g_qeglobals.d_savedinfo.colors[iIndex][1]; + if ( g_qeglobals.d_savedinfo.colors[iIndex][2] > largest ) + largest = g_qeglobals.d_savedinfo.colors[iIndex][2]; + + if ( largest == 0.0F ) + { + g_qeglobals.d_savedinfo.colors[iIndex][0] = 1.0F; + g_qeglobals.d_savedinfo.colors[iIndex][1] = 1.0F; + g_qeglobals.d_savedinfo.colors[iIndex][2] = 1.0F; + } + else + { + float scaler = 1.0F / largest; + + g_qeglobals.d_savedinfo.colors[iIndex][0] *= scaler; + g_qeglobals.d_savedinfo.colors[iIndex][1] *= scaler; + g_qeglobals.d_savedinfo.colors[iIndex][2] *= scaler; + } + } + + Sys_UpdateWindows (W_ALL); + + return true; +} + + +/* Copied from MSDN */ + +BOOL DoMru(HWND hWnd,WORD wId) +{ + char szFileName[128]; + OFSTRUCT of; + BOOL fExist; + + GetMenuItem(g_qeglobals.d_lpMruMenu, wId, TRUE, szFileName, sizeof(szFileName)); + + // Test if the file exists. + + fExist = OpenFile(szFileName ,&of,OF_EXIST) != HFILE_ERROR; + + if (fExist) { + + // Place the file on the top of MRU. + AddNewItem(g_qeglobals.d_lpMruMenu,(LPSTR)szFileName); + + // Now perform opening this file !!! + Map_LoadFile (szFileName); + } + else + // Remove the file on MRU. + DelMenuItem(g_qeglobals.d_lpMruMenu,wId,TRUE); + + // Refresh the File menu. + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(hWnd),0), + ID_FILE_EXIT); + + return fExist; +} + + +/* handle all WM_COMMAND messages here */ +LONG WINAPI CommandHandler ( + HWND hWnd, + WPARAM wParam, + LPARAM lParam) +{ + HMENU hMenu; + + switch (LOWORD(wParam)) + { +// +// file menu +// + case ID_FILE_EXIT: + /* exit application */ + if (!ConfirmModified()) + return TRUE; + + PostMessage (hWnd, WM_CLOSE, 0, 0L); + break; + + case ID_FILE_OPEN: + if (!ConfirmModified()) + return TRUE; + OpenDialog (); + break; + + case ID_FILE_NEW: + if (!ConfirmModified()) + return TRUE; + Map_New (); + break; + case ID_FILE_SAVE: + if (!strcmp(currentmap, "unnamed.map")) + SaveAsDialog (); + else + Map_SaveFile (currentmap, false); // ignore region + break; + case ID_FILE_SAVEAS: + SaveAsDialog (); + break; + + case ID_FILE_LOADPROJECT: + if (!ConfirmModified()) + return TRUE; + ProjectDialog (); + break; + + case ID_FILE_POINTFILE: + if (g_qeglobals.d_pointfile_display_list) + Pointfile_Clear (); + else + Pointfile_Check (); + break; + +// +// view menu +// + case ID_VIEW_ENTITY: + SetInspectorMode(W_ENTITY); + break; + case ID_VIEW_CONSOLE: + SetInspectorMode(W_CONSOLE); + break; + case ID_VIEW_TEXTURE: + SetInspectorMode(W_TEXTURE); + break; + + case ID_VIEW_100: + g_qeglobals.d_xy.scale = 1; + Sys_UpdateWindows (W_XY|W_XY_OVERLAY); + break; + case ID_VIEW_ZOOMIN: + g_qeglobals.d_xy.scale *= 5.0/4; + if (g_qeglobals.d_xy.scale > 16) + g_qeglobals.d_xy.scale = 16; + Sys_UpdateWindows (W_XY|W_XY_OVERLAY); + break; + case ID_VIEW_ZOOMOUT: + g_qeglobals.d_xy.scale *= 4.0/5; + if (g_qeglobals.d_xy.scale < 0.1) + g_qeglobals.d_xy.scale = 0.1; + Sys_UpdateWindows (W_XY|W_XY_OVERLAY); + break; + + case ID_VIEW_Z100: + z.scale = 1; + Sys_UpdateWindows (W_Z|W_Z_OVERLAY); + break; + case ID_VIEW_ZZOOMIN: + z.scale *= 5.0/4; + if (z.scale > 4) + z.scale = 4; + Sys_UpdateWindows (W_Z|W_Z_OVERLAY); + break; + case ID_VIEW_ZZOOMOUT: + z.scale *= 4.0/5; + if (z.scale < 0.125) + z.scale = 0.125; + Sys_UpdateWindows (W_Z|W_Z_OVERLAY); + break; + + case ID_VIEW_CENTER: + camera.angles[ROLL] = camera.angles[PITCH] = 0; + camera.angles[YAW] = 22.5 * + floor( (camera.angles[YAW]+11)/22.5 ); + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + break; + + case ID_VIEW_UPFLOOR: + Cam_ChangeFloor (true); + break; + case ID_VIEW_DOWNFLOOR: + Cam_ChangeFloor (false); + break; + + case ID_VIEW_SHOWNAMES: + g_qeglobals.d_savedinfo.show_names = !g_qeglobals.d_savedinfo.show_names; + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWNAMES, MF_BYCOMMAND | (g_qeglobals.d_savedinfo.show_names ? MF_CHECKED : MF_UNCHECKED) ); + Map_BuildBrushData(); + Sys_UpdateWindows (W_XY); + break; + + case ID_VIEW_SHOWCOORDINATES: + g_qeglobals.d_savedinfo.show_coordinates ^= 1; + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | (g_qeglobals.d_savedinfo.show_coordinates ? MF_CHECKED : MF_UNCHECKED) ); + Sys_UpdateWindows (W_XY); + break; + + case ID_VIEW_SHOWBLOCKS: + g_qeglobals.show_blocks ^= 1; + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWBLOCKS, MF_BYCOMMAND | (g_qeglobals.show_blocks ? MF_CHECKED : MF_UNCHECKED) ); + Sys_UpdateWindows (W_XY); + break; + + case ID_VIEW_SHOWLIGHTS: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_LIGHTS ) & EXCLUDE_LIGHTS ) + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED ); + else + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_CHECKED ); + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + case ID_VIEW_SHOWPATH: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_PATHS ) & EXCLUDE_PATHS ) + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED ); + else + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_CHECKED ); + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + case ID_VIEW_SHOWENT: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_ENT ) & EXCLUDE_ENT ) + CheckMenuItem( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWENT, MF_BYCOMMAND | MF_UNCHECKED); + else + CheckMenuItem( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWENT, MF_BYCOMMAND | MF_CHECKED); + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + case ID_VIEW_SHOWWATER: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_WATER ) & EXCLUDE_WATER ) + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED ); + else + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_CHECKED ); + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + case ID_VIEW_SHOWCLIP: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CLIP ) & EXCLUDE_CLIP ) + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED ); + else + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_CHECKED ); + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + case ID_VIEW_SHOWDETAIL: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_DETAIL ) & EXCLUDE_DETAIL ) + { + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWDETAIL, MF_BYCOMMAND | MF_UNCHECKED ); + SetWindowText (g_qeglobals.d_hwndCamera, "Camera View (DETAIL EXCLUDED)"); + } + else + { + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWDETAIL, MF_BYCOMMAND | MF_CHECKED ); + SetWindowText (g_qeglobals.d_hwndCamera, "Camera View"); + } + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + case ID_VIEW_SHOWWORLD: + if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_WORLD ) & EXCLUDE_WORLD ) + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED ); + else + CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_CHECKED ); + Sys_UpdateWindows (W_XY|W_CAMERA); + break; + + +// +// grid menu +// + case ID_GRID_1: + case ID_GRID_2: + case ID_GRID_4: + case ID_GRID_8: + case ID_GRID_16: + case ID_GRID_32: + case ID_GRID_64: + { + hMenu = GetMenu(hWnd); + + CheckMenuItem(hMenu, ID_GRID_1, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_2, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_4, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_8, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_16, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_32, MF_BYCOMMAND | MF_UNCHECKED); + CheckMenuItem(hMenu, ID_GRID_64, MF_BYCOMMAND | MF_UNCHECKED); + + switch (LOWORD(wParam)) + { + case ID_GRID_1: g_qeglobals.d_gridsize = 0; break; + case ID_GRID_2: g_qeglobals.d_gridsize = 1; break; + case ID_GRID_4: g_qeglobals.d_gridsize = 2; break; + case ID_GRID_8: g_qeglobals.d_gridsize = 3; break; + case ID_GRID_16: g_qeglobals.d_gridsize = 4; break; + case ID_GRID_32: g_qeglobals.d_gridsize = 5; break; + case ID_GRID_64: g_qeglobals.d_gridsize = 6; break; + } + g_qeglobals.d_gridsize = 1 << g_qeglobals.d_gridsize; + + CheckMenuItem(hMenu, LOWORD(wParam), MF_BYCOMMAND | MF_CHECKED); + Sys_UpdateWindows (W_XY|W_Z); + break; + } + +// +// texture menu +// + case ID_VIEW_NEAREST: + case ID_VIEW_NEARESTMIPMAP: + case ID_VIEW_LINEAR: + case ID_VIEW_BILINEAR: + case ID_VIEW_BILINEARMIPMAP: + case ID_VIEW_TRILINEAR: + case ID_TEXTURES_WIREFRAME: + case ID_TEXTURES_FLATSHADE: + Texture_SetMode (LOWORD(wParam)); + break; + + case ID_TEXTURES_SHOWINUSE: + Sys_BeginWait (); + Texture_ShowInuse (); + SetInspectorMode(W_TEXTURE); + break; + + case ID_TEXTURES_INSPECTOR: + DoSurface (); + break; + + case CMD_TEXTUREWAD: + case CMD_TEXTUREWAD+1: + case CMD_TEXTUREWAD+2: + case CMD_TEXTUREWAD+3: + case CMD_TEXTUREWAD+4: + case CMD_TEXTUREWAD+5: + case CMD_TEXTUREWAD+6: + case CMD_TEXTUREWAD+7: + case CMD_TEXTUREWAD+8: + case CMD_TEXTUREWAD+9: + case CMD_TEXTUREWAD+10: + case CMD_TEXTUREWAD+11: + case CMD_TEXTUREWAD+12: + case CMD_TEXTUREWAD+13: + case CMD_TEXTUREWAD+14: + case CMD_TEXTUREWAD+15: + case CMD_TEXTUREWAD+16: + case CMD_TEXTUREWAD+17: + case CMD_TEXTUREWAD+18: + case CMD_TEXTUREWAD+19: + case CMD_TEXTUREWAD+20: + case CMD_TEXTUREWAD+21: + case CMD_TEXTUREWAD+22: + case CMD_TEXTUREWAD+23: + case CMD_TEXTUREWAD+24: + case CMD_TEXTUREWAD+25: + case CMD_TEXTUREWAD+26: + case CMD_TEXTUREWAD+27: + case CMD_TEXTUREWAD+28: + case CMD_TEXTUREWAD+29: + case CMD_TEXTUREWAD+30: + case CMD_TEXTUREWAD+31: + Sys_BeginWait (); + Texture_ShowDirectory (LOWORD(wParam)); + SetInspectorMode(W_TEXTURE); + break; + +// +// bsp menu +// + case CMD_BSPCOMMAND: + case CMD_BSPCOMMAND+1: + case CMD_BSPCOMMAND+2: + case CMD_BSPCOMMAND+3: + case CMD_BSPCOMMAND+4: + case CMD_BSPCOMMAND+5: + case CMD_BSPCOMMAND+6: + case CMD_BSPCOMMAND+7: + case CMD_BSPCOMMAND+8: + case CMD_BSPCOMMAND+9: + case CMD_BSPCOMMAND+10: + case CMD_BSPCOMMAND+11: + case CMD_BSPCOMMAND+12: + case CMD_BSPCOMMAND+13: + case CMD_BSPCOMMAND+14: + case CMD_BSPCOMMAND+15: + case CMD_BSPCOMMAND+16: + case CMD_BSPCOMMAND+17: + case CMD_BSPCOMMAND+18: + case CMD_BSPCOMMAND+19: + case CMD_BSPCOMMAND+20: + case CMD_BSPCOMMAND+21: + case CMD_BSPCOMMAND+22: + case CMD_BSPCOMMAND+23: + case CMD_BSPCOMMAND+24: + case CMD_BSPCOMMAND+25: + case CMD_BSPCOMMAND+26: + case CMD_BSPCOMMAND+27: + case CMD_BSPCOMMAND+28: + case CMD_BSPCOMMAND+29: + case CMD_BSPCOMMAND+30: + case CMD_BSPCOMMAND+31: + { + extern char *bsp_commands[256]; + + RunBsp (bsp_commands[LOWORD(wParam-CMD_BSPCOMMAND)]); + } + break; + +// +// misc menu +// + case ID_MISC_BENCHMARK: + SendMessage ( g_qeglobals.d_hwndCamera, + WM_USER+267, 0, 0); + break; + + case ID_TEXTUREBK: + DoColor(COLOR_TEXTUREBACK); + Sys_UpdateWindows (W_ALL); + break; + + case ID_MISC_SELECTENTITYCOLOR: + { + extern int inspector_mode; + + if ( ( inspector_mode == W_ENTITY ) && DoColor(COLOR_ENTITY) == true ) + { + extern void AddProp( void ); + + char buffer[100]; + + sprintf( buffer, "%f %f %f", g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][0], + g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][1], + g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][2] ); + + SetWindowText( hwndEnt[EntValueField], buffer ); + SetWindowText( hwndEnt[EntKeyField], "_color" ); + AddProp(); + } + Sys_UpdateWindows( W_ALL ); + } + break; + + case ID_MISC_PRINTXY: + WXY_Print(); + break; + + case ID_COLORS_XYBK: + DoColor(COLOR_GRIDBACK); + Sys_UpdateWindows (W_ALL); + break; + + case ID_COLORS_MAJOR: + DoColor(COLOR_GRIDMAJOR); + Sys_UpdateWindows (W_ALL); + break; + + case ID_COLORS_MINOR: + DoColor(COLOR_GRIDMINOR); + Sys_UpdateWindows (W_ALL); + break; + + case ID_MISC_GAMMA: + DoGamma(); + break; + + case ID_MISC_FINDBRUSH: + DoFind(); + break; + + case ID_MISC_NEXTLEAKSPOT: + Pointfile_Next(); + break; + case ID_MISC_PREVIOUSLEAKSPOT: + Pointfile_Prev(); + break; + +// +// brush menu +// + case ID_BRUSH_3SIDED: + Brush_MakeSided (3); + break; + case ID_BRUSH_4SIDED: + Brush_MakeSided (4); + break; + case ID_BRUSH_5SIDED: + Brush_MakeSided (5); + break; + case ID_BRUSH_6SIDED: + Brush_MakeSided (6); + break; + case ID_BRUSH_7SIDED: + Brush_MakeSided (7); + break; + case ID_BRUSH_8SIDED: + Brush_MakeSided (8); + break; + case ID_BRUSH_9SIDED: + Brush_MakeSided (9); + break; + case ID_BRUSH_ARBITRARYSIDED: + DoSides (); + break; + +// +// select menu +// + case ID_BRUSH_FLIPX: + Select_FlipAxis (0); + break; + case ID_BRUSH_FLIPY: + Select_FlipAxis (1); + break; + case ID_BRUSH_FLIPZ: + Select_FlipAxis (2); + break; + case ID_BRUSH_ROTATEX: + Select_RotateAxis (0, 90); + break; + case ID_BRUSH_ROTATEY: + Select_RotateAxis (1, 90); + break; + case ID_BRUSH_ROTATEZ: + Select_RotateAxis (2, 90); + break; + + case ID_SELECTION_ARBITRARYROTATION: + DoRotate (); + break; + + case ID_SELECTION_UNGROUPENTITY: + Select_Ungroup (); + break; + + case ID_SELECTION_CONNECT: + ConnectEntities (); + break; + + case ID_SELECTION_DRAGVERTECIES: + if (g_qeglobals.d_select_mode == sel_vertex) + { + g_qeglobals.d_select_mode = sel_brush; + Sys_UpdateWindows (W_ALL); + } + else + { + SetupVertexSelection (); + if (g_qeglobals.d_numpoints) + g_qeglobals.d_select_mode = sel_vertex; + } + break; + case ID_SELECTION_DRAGEDGES: + if (g_qeglobals.d_select_mode == sel_edge) + { + g_qeglobals.d_select_mode = sel_brush; + Sys_UpdateWindows (W_ALL); + } + else + { + SetupVertexSelection (); + if (g_qeglobals.d_numpoints) + g_qeglobals.d_select_mode = sel_edge; + } + break; + + case ID_SELECTION_SELECTPARTIALTALL: + Select_PartialTall (); + break; + case ID_SELECTION_SELECTCOMPLETETALL: + Select_CompleteTall (); + break; + case ID_SELECTION_SELECTTOUCHING: + Select_Touching (); + break; + case ID_SELECTION_SELECTINSIDE: + Select_Inside (); + break; + case ID_SELECTION_CSGSUBTRACT: + CSG_Subtract (); + break; + case ID_SELECTION_MAKEHOLLOW: + CSG_MakeHollow (); + break; + + case ID_SELECTION_CLONE: + Select_Clone (); + break; + case ID_SELECTION_DELETE: + Select_Delete (); + break; + case ID_SELECTION_DESELECT: + Select_Deselect (); + break; + + case ID_SELECTION_MAKE_DETAIL: + Select_MakeDetail (); + break; + case ID_SELECTION_MAKE_STRUCTURAL: + Select_MakeStructural (); + break; + + +// +// region menu +// + case ID_REGION_OFF: + Map_RegionOff (); + break; + case ID_REGION_SETXY: + Map_RegionXY (); + break; + case ID_REGION_SETTALLBRUSH: + Map_RegionTallBrush (); + break; + case ID_REGION_SETBRUSH: + Map_RegionBrush (); + break; + case ID_REGION_SETSELECTION: + Map_RegionSelectedBrushes (); + break; + + case IDMRU+1: + case IDMRU+2: + case IDMRU+3: + case IDMRU+4: + case IDMRU+5: + case IDMRU+6: + case IDMRU+7: + case IDMRU+8: + case IDMRU+9: + DoMru(hWnd,LOWORD(wParam)); + break; + +// +// help menu +// + + case ID_HELP_ABOUT: + DoAbout(); + break; + + default: + return FALSE; + } + + return TRUE; +} + +/* +============ +WMAIN_WndProc +============ +*/ +LONG WINAPI WMAIN_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LONG lRet = 1; + RECT rect; + HDC maindc; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_TIMER: + QE_CountBrushesAndUpdateStatusBar(); + QE_CheckAutoSave(); + return 0; + + case WM_DESTROY: + SaveMruInReg(g_qeglobals.d_lpMruMenu,"Software\\id\\QuakeEd4\\MRU"); + DeleteMruMenu(g_qeglobals.d_lpMruMenu); + PostQuitMessage(0); + KillTimer( hWnd, QE_TIMER0 ); + return 0; + + case WM_CREATE: + maindc = GetDC(hWnd); +// QEW_SetupPixelFormat(maindc, false); + g_qeglobals.d_lpMruMenu = CreateMruMenuDefault(); + LoadMruInReg(g_qeglobals.d_lpMruMenu,"Software\\id\\QuakeEd4\\MRU"); + + // Refresh the File menu. + PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(hWnd),0), + ID_FILE_EXIT); + + return 0; + + case WM_SIZE: + // resize the status window + MoveWindow( g_qeglobals.d_hwndStatus, -100, 100, 10, 10, true); + return 0; + + case WM_KEYDOWN: + return QE_KeyDown (wParam); + + case WM_CLOSE: + /* call destroy window to cleanup and go away */ + SaveWindowState(g_qeglobals.d_hwndXY, "xywindow"); + SaveWindowState(g_qeglobals.d_hwndCamera, "camerawindow"); + SaveWindowState(g_qeglobals.d_hwndZ, "zwindow"); + SaveWindowState(g_qeglobals.d_hwndEntity, "EntityWindow"); + SaveWindowState(g_qeglobals.d_hwndMain, "mainwindow"); + + // FIXME: is this right? + SaveRegistryInfo("SavedInfo", &g_qeglobals.d_savedinfo, sizeof(g_qeglobals.d_savedinfo)); + DestroyWindow (hWnd); + return 0; + + case WM_COMMAND: + return CommandHandler (hWnd, wParam, lParam); + return 0; + } + + return DefWindowProc (hWnd, uMsg, wParam, lParam); +} + + + + +/* +============== +Main_Create +============== +*/ +void Main_Create (HINSTANCE hInstance) +{ + WNDCLASS wc; + int i; + HMENU hMenu; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WMAIN_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); + wc.lpszClassName = "QUAKE_MAIN"; + + if (!RegisterClass (&wc) ) + Error ("WCam_Register: failed"); + + + g_qeglobals.d_hwndMain = CreateWindow ("QUAKE_MAIN" , + "QuakeEd 3", + WS_OVERLAPPEDWINDOW | + WS_CLIPSIBLINGS | + WS_CLIPCHILDREN, + 0,0,screen_width,screen_height+GetSystemMetrics(SM_CYSIZE), // size + 0, + 0, // no menu + hInstance, + NULL); + if (!g_qeglobals.d_hwndMain) + Error ("Couldn't create main window"); + + /* create a timer so that we can count brushes */ + SetTimer( g_qeglobals.d_hwndMain, + QE_TIMER0, + 1000, + NULL ); + + LoadWindowState(g_qeglobals.d_hwndMain, "mainwindow"); + + s_hwndToolbar = CreateToolBar(hInstance); + + g_qeglobals.d_hwndStatus = CreateMyStatusWindow(hInstance); + + // + // load misc info from registry + // + i = sizeof(g_qeglobals.d_savedinfo); + LoadRegistryInfo("SavedInfo", &g_qeglobals.d_savedinfo, &i); + + if (g_qeglobals.d_savedinfo.iSize != sizeof(g_qeglobals.d_savedinfo)) + { + // fill in new defaults + + g_qeglobals.d_savedinfo.iSize = sizeof(g_qeglobals.d_savedinfo); + g_qeglobals.d_savedinfo.fGamma = 1.0; + g_qeglobals.d_savedinfo.iTexMenu = ID_VIEW_NEAREST; + + g_qeglobals.d_savedinfo.exclude = 0; + g_qeglobals.d_savedinfo.show_coordinates = true; + g_qeglobals.d_savedinfo.show_names = true; + + for (i=0 ; i<3 ; i++) + { + g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.75; + g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5; + g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25; + } + } + + if ( ( hMenu = GetMenu( g_qeglobals.d_hwndMain ) ) != 0 ) + { + /* + ** by default all of these are checked because that's how they're defined in the menu editor + */ + if ( !g_qeglobals.d_savedinfo.show_names ) + CheckMenuItem( hMenu, ID_VIEW_SHOWNAMES, MF_BYCOMMAND | MF_UNCHECKED ); + if ( !g_qeglobals.d_savedinfo.show_coordinates ) + CheckMenuItem( hMenu, ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | MF_UNCHECKED ); + + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS ) + CheckMenuItem( hMenu, ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED ); + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT ) + CheckMenuItem( hMenu, ID_VIEW_ENTITY, MF_BYCOMMAND | MF_UNCHECKED ); + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS ) + CheckMenuItem( hMenu, ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED ); + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER ) + CheckMenuItem( hMenu, ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED ); + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD ) + CheckMenuItem( hMenu, ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED ); + if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP ) + CheckMenuItem( hMenu, ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED ); + } + + ShowWindow (g_qeglobals.d_hwndMain, SW_SHOWDEFAULT); +} + + +/* +============================================================= + +REGISTRY INFO + +============================================================= +*/ + +BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize) +{ + LONG lres; + DWORD dwDisp; + HKEY hKeyId; + + lres = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\id\\QuakeEd4", 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyId, &dwDisp); + + if (lres != ERROR_SUCCESS) + return FALSE; + + lres = RegSetValueEx(hKeyId, pszName, 0, REG_BINARY, pvBuf, lSize); + + RegCloseKey(hKeyId); + + if (lres != ERROR_SUCCESS) + return FALSE; + + return TRUE; +} + +BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize) +{ + HKEY hKey; + long lres, lType, lSize; + + if (plSize == NULL) + plSize = &lSize; + + lres = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\id\\QuakeEd4", 0, KEY_READ, &hKey); + + if (lres != ERROR_SUCCESS) + return FALSE; + + lres = RegQueryValueEx(hKey, pszName, NULL, &lType, pvBuf, plSize); + + RegCloseKey(hKey); + + if (lres != ERROR_SUCCESS) + return FALSE; + + return TRUE; +} + +BOOL SaveWindowState(HWND hWnd, const char *pszName) +{ + RECT rc; + + GetWindowRect(hWnd, &rc); + if (hWnd != g_qeglobals.d_hwndMain) + MapWindowPoints(NULL, g_qeglobals.d_hwndMain, (POINT *)&rc, 2); + return SaveRegistryInfo(pszName, &rc, sizeof(rc)); +} + + +BOOL LoadWindowState(HWND hWnd, const char *pszName) +{ + RECT rc; + LONG lSize = sizeof(rc); + + if (LoadRegistryInfo(pszName, &rc, &lSize)) + { + if (rc.left < 0) + rc.left = 0; + if (rc.top < 0) + rc.top = 0; + if (rc.right < rc.left + 16) + rc.right = rc.left + 16; + if (rc.bottom < rc.top + 16) + rc.bottom = rc.top + 16; + + MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, + rc.bottom - rc.top, FALSE); + return TRUE; + } + + return FALSE; +} + +/* +=============================================================== + + STATUS WINDOW + +=============================================================== +*/ + +void Sys_UpdateStatusBar( void ) +{ + extern int g_numbrushes, g_numentities; + + char numbrushbuffer[100]=""; + + sprintf( numbrushbuffer, "Brushes: %d Entities: %d", g_numbrushes, g_numentities ); + + Sys_Status( numbrushbuffer, 2 ); +} + +void Sys_Status(const char *psz, int part ) +{ + SendMessage(g_qeglobals.d_hwndStatus, SB_SETTEXT, part, (LPARAM)psz); +} + +static HWND CreateMyStatusWindow(HINSTANCE hInst) +{ + HWND hWnd; + int partsize[3] = { 300, 1100, -1 }; + + hWnd = CreateWindowEx( WS_EX_TOPMOST, // no extended styles + STATUSCLASSNAME, // status bar + "", // no text + WS_CHILD | WS_BORDER | WS_VISIBLE, // styles + -100, -100, 10, 10, // x, y, cx, cy + g_qeglobals.d_hwndMain, // parent window + (HMENU)100, // window ID + hInst, // instance + NULL); // window data + + SendMessage( hWnd, SB_SETPARTS, 3, ( long ) partsize ); + + return hWnd; +} + +//============================================================== + +#define NUMBUTTONS 15 +HWND CreateToolBar(HINSTANCE hinst) +{ + HWND hwndTB; + TBADDBITMAP tbab; + TBBUTTON tbb[NUMBUTTONS]; + + // Ensure that the common control DLL is loaded. + + InitCommonControls(); + + // Create a toolbar that the user can customize and that has a + // tooltip associated with it. + + hwndTB = CreateWindowEx(0, TOOLBARCLASSNAME, (LPSTR) NULL, + WS_CHILD | TBSTYLE_TOOLTIPS | CCS_ADJUSTABLE | WS_BORDER, + 0, 0, 0, 0, g_qeglobals.d_hwndMain, (HMENU) IDR_TOOLBAR1, hinst, NULL); + + // Send the TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + + SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0); + + // Add the bitmap containing button images to the toolbar. + + tbab.hInst = hinst; + tbab.nID = IDR_TOOLBAR1; + SendMessage(hwndTB, TB_ADDBITMAP, (WPARAM)NUMBUTTONS, (WPARAM) &tbab); + + // Fill the TBBUTTON array with button information, and add the + // buttons to the toolbar. + + tbb[0].iBitmap = 0; + tbb[0].idCommand = ID_BRUSH_FLIPX; + tbb[0].fsState = TBSTATE_ENABLED; + tbb[0].fsStyle = TBSTYLE_BUTTON; + tbb[0].dwData = 0; + tbb[0].iString = 0; + + tbb[1].iBitmap = 2; + tbb[1].idCommand = ID_BRUSH_FLIPY; + tbb[1].fsState = TBSTATE_ENABLED; + tbb[1].fsStyle = TBSTYLE_BUTTON; + tbb[1].dwData = 0; + tbb[1].iString = 0; + + tbb[2].iBitmap = 4; + tbb[2].idCommand = ID_BRUSH_FLIPZ; + tbb[2].fsState = TBSTATE_ENABLED; + tbb[2].fsStyle = TBSTYLE_BUTTON; + tbb[2].dwData = 0; + tbb[2].iString = 0; + + tbb[3].iBitmap = 1; + tbb[3].idCommand = ID_BRUSH_ROTATEX; + tbb[3].fsState = TBSTATE_ENABLED; + tbb[3].fsStyle = TBSTYLE_BUTTON; + tbb[3].dwData = 0; + tbb[3].iString = 0; + + tbb[4].iBitmap = 3; + tbb[4].idCommand = ID_BRUSH_ROTATEY; + tbb[4].fsState = TBSTATE_ENABLED; + tbb[4].fsStyle = TBSTYLE_BUTTON; + tbb[4].dwData = 0; + tbb[4].iString = 0; + + tbb[5].iBitmap = 5; + tbb[5].idCommand = ID_BRUSH_ROTATEZ; + tbb[5].fsState = TBSTATE_ENABLED; + tbb[5].fsStyle = TBSTYLE_BUTTON; + tbb[5].dwData = 0; + tbb[5].iString = 0; + + tbb[6].iBitmap = 6; + tbb[6].idCommand = ID_SELECTION_SELECTCOMPLETETALL; + tbb[6].fsState = TBSTATE_ENABLED; + tbb[6].fsStyle = TBSTYLE_BUTTON; + tbb[6].dwData = 0; + tbb[6].iString = 0; + + tbb[7].iBitmap = 7; + tbb[7].idCommand = ID_SELECTION_SELECTTOUCHING; + tbb[7].fsState = TBSTATE_ENABLED; + tbb[7].fsStyle = TBSTYLE_BUTTON; + tbb[7].dwData = 0; + tbb[7].iString = 0; + + tbb[8].iBitmap = 8; + tbb[8].idCommand = ID_SELECTION_SELECTPARTIALTALL; + tbb[8].fsState = TBSTATE_ENABLED; + tbb[8].fsStyle = TBSTYLE_BUTTON; + tbb[8].dwData = 0; + tbb[8].iString = 0; + + + tbb[9].iBitmap = 9; + tbb[9].idCommand = ID_SELECTION_SELECTINSIDE; + tbb[9].fsState = TBSTATE_ENABLED; + tbb[9].fsStyle = TBSTYLE_BUTTON; + tbb[9].dwData = 0; + tbb[9].iString = 0; + + tbb[10].iBitmap = 10; + tbb[10].idCommand = ID_SELECTION_CSGSUBTRACT; + tbb[10].fsState = TBSTATE_ENABLED; + tbb[10].fsStyle = TBSTYLE_BUTTON; + tbb[10].dwData = 0; + tbb[10].iString = 0; + + + tbb[11].iBitmap = 11; + tbb[11].idCommand = ID_SELECTION_MAKEHOLLOW; + tbb[11].fsState = TBSTATE_ENABLED; + tbb[11].fsStyle = TBSTYLE_BUTTON; + tbb[11].dwData = 0; + tbb[11].iString = 0; + + tbb[12].iBitmap = 12; + tbb[12].idCommand = ID_TEXTURES_WIREFRAME; + tbb[12].fsState = TBSTATE_ENABLED; + tbb[12].fsStyle = TBSTYLE_BUTTON; + tbb[12].dwData = 0; + tbb[12].iString = 0; + + tbb[13].iBitmap = 13; + tbb[13].idCommand = ID_TEXTURES_FLATSHADE; + tbb[13].fsState = TBSTATE_ENABLED; + tbb[13].fsStyle = TBSTYLE_BUTTON; + tbb[13].dwData = 0; + tbb[13].iString = 0; + + tbb[14].iBitmap = 14; + tbb[14].idCommand = ID_VIEW_TRILINEAR; + tbb[14].fsState = TBSTATE_ENABLED; + tbb[14].fsStyle = TBSTYLE_BUTTON; + tbb[14].dwData = 0; + tbb[14].iString = 0; + + SendMessage(hwndTB, TB_ADDBUTTONS, (WPARAM)NUMBUTTONS, + (LPARAM) (LPTBBUTTON) &tbb); + + ShowWindow(hwndTB, SW_SHOW); + + return hwndTB; +} + diff --git a/tools/quake2/extra/qe4/win_qe3.aps b/tools/quake2/extra/qe4/win_qe3.aps new file mode 100644 index 0000000000000000000000000000000000000000..9be3e7d4015343730c7c75a7b43042f0422584cf GIT binary patch literal 78688 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 Qt#12RCoG_NY*#1zKl-IdC;$Ke literal 0 HcmV?d00001 diff --git a/tools/quake2/extra/qe4/win_qe3.c b/tools/quake2/extra/qe4/win_qe3.c new file mode 100644 index 00000000..297a58d9 --- /dev/null +++ b/tools/quake2/extra/qe4/win_qe3.c @@ -0,0 +1,605 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" +#include "mru.h" + +int screen_width; +int screen_height; +qboolean have_quit; + +int update_bits; + +HANDLE bsp_process; + +//=========================================== + +void Sys_SetTitle (char *text) +{ + SetWindowText (g_qeglobals.d_hwndMain, text); +} + +HCURSOR waitcursor; + +void Sys_BeginWait (void) +{ + waitcursor = SetCursor (LoadCursor (NULL, IDC_WAIT)); +} + +void Sys_EndWait (void) +{ + if (waitcursor) + { + SetCursor (waitcursor); + waitcursor = NULL; + } +} + + +void Sys_GetCursorPos (int *x, int *y) +{ + POINT lpPoint; + + GetCursorPos (&lpPoint); + *x = lpPoint.x; + *y = lpPoint.y; +} + +void Sys_SetCursorPos (int x, int y) +{ + SetCursorPos (x, y); +} + +void Sys_UpdateWindows (int bits) +{ +// Sys_Printf("updating 0x%X\n", bits); + update_bits |= bits; +//update_bits = -1; +} + + +void Sys_Beep (void) +{ + MessageBeep (MB_ICONASTERISK); +} + +char *TranslateString (char *buf) +{ + static char buf2[32768]; + int i, l; + char *out; + + l = strlen(buf); + out = buf2; + for (i=0 ; iepairs ; ep ; ep=ep->next) + { + if (ep->key[0] == 'b' && ep->key[1] == 's' && ep->key[2] == 'p') + { + bsp_commands[i] = ep->key; + AppendMenu (hmenu, MF_ENABLED|MF_STRING, + CMD_BSPCOMMAND+i, (LPCTSTR)ep->key); + i++; + } + } + count = i; +} + +//============================================== + +/* +=============== +CheckBspProcess + +See if the BSP is done yet +=============== +*/ +void CheckBspProcess (void) +{ + char outputpath[1024]; + char temppath[512]; + DWORD exitcode; + char *out; + BOOL ret; + + if (!bsp_process) + return; + + ret = GetExitCodeProcess (bsp_process, &exitcode); + if (!ret) + Error ("GetExitCodeProcess failed"); + if (exitcode == STILL_ACTIVE) + return; + + bsp_process = 0; + + GetTempPath(512, temppath); + sprintf (outputpath, "%sjunk.txt", temppath); + + LoadFile (outputpath, (void *)&out); + Sys_Printf ("%s", out); + Sys_Printf ("\ncompleted.\n"); + free (out); + Sys_Beep (); + + Pointfile_Check (); +} + +extern int cambuttonstate; + +/* +================== +WinMain + +================== +*/ +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance + ,LPSTR lpCmdLine, int nCmdShow) +{ + MSG msg; + double time, oldtime, delta; + HACCEL accelerators; + + g_qeglobals.d_hInstance = hInstance; + + InitCommonControls (); + + screen_width = GetSystemMetrics (SM_CXFULLSCREEN); + screen_height = GetSystemMetrics (SM_CYFULLSCREEN); + + // hack for broken NT 4.0 dual screen + if (screen_width > 2*screen_height) + screen_width /= 2; + + accelerators = LoadAccelerators (hInstance + , MAKEINTRESOURCE(IDR_ACCELERATOR1)); + if (!accelerators) + Error ("LoadAccelerators failed"); + + Main_Create (hInstance); + + WCam_Create (hInstance); + WXY_Create (hInstance); + WZ_Create (hInstance); + CreateEntityWindow(hInstance); + + // the project file can be specified on the command line, + // or implicitly found in the scripts directory + if (lpCmdLine && strlen(lpCmdLine)) + { + ParseCommandLine (lpCmdLine); + if (!QE_LoadProject(argv[1])) + Error ("Couldn't load %s project file", argv[1]); + } + else if (!QE_LoadProject("scripts/quake.qe4")) + Error ("Couldn't load scripts/quake.qe4 project file"); + + QE_Init (); + + Sys_Printf ("Entering message loop\n"); + + oldtime = Sys_DoubleTime (); + + while (!have_quit) + { + Sys_EndWait (); // remove wait cursor if active + + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (!TranslateAccelerator(g_qeglobals.d_hwndMain, accelerators, &msg) ) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + if (msg.message == WM_QUIT) + have_quit = true; + } + + + CheckBspProcess (); + + time = Sys_DoubleTime (); + delta = time - oldtime; + oldtime = time; + if (delta > 0.2) + delta = 0.2; + + // run time dependant behavior + Cam_MouseControl (delta); + + // update any windows now + if (update_bits & W_CAMERA) + { + InvalidateRect(g_qeglobals.d_hwndCamera, NULL, false); + UpdateWindow (g_qeglobals.d_hwndCamera); + } + if (update_bits & (W_Z | W_Z_OVERLAY) ) + { + InvalidateRect(g_qeglobals.d_hwndZ, NULL, false); + UpdateWindow (g_qeglobals.d_hwndZ); + } + + if ( update_bits & W_TEXTURE ) + { + InvalidateRect(g_qeglobals.d_hwndTexture, NULL, false); + UpdateWindow (g_qeglobals.d_hwndEntity); + } + + if (update_bits & (W_XY | W_XY_OVERLAY)) + { + InvalidateRect(g_qeglobals.d_hwndXY, NULL, false); + UpdateWindow (g_qeglobals.d_hwndXY); + } + + update_bits = 0; + + if (!cambuttonstate && !have_quit) + { // if not driving in the camera view, block + WaitMessage (); + } + + } + + /* return success of application */ + return TRUE; + +} + diff --git a/tools/quake2/extra/qe4/win_qe3.rc b/tools/quake2/extra/qe4/win_qe3.rc new file mode 100644 index 00000000..06dab11e --- /dev/null +++ b/tools/quake2/extra/qe4/win_qe3.rc @@ -0,0 +1,693 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New", ID_FILE_NEW + MENUITEM "&Open", ID_FILE_OPEN + MENUITEM "&Save", ID_FILE_SAVE + MENUITEM "Save &as...", ID_FILE_SAVEAS + MENUITEM "&Pointfile", ID_FILE_POINTFILE + MENUITEM "Load &project", ID_FILE_LOADPROJECT + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Copy brush", ID_EDIT_COPYBRUSH, GRAYED + MENUITEM "&Paste brush", ID_EDIT_PASTEBRUSH, GRAYED + END + POPUP "&View" + BEGIN + MENUITEM "Texture View\tT", ID_VIEW_TEXTURE + MENUITEM "Console View\tO", ID_VIEW_CONSOLE + MENUITEM "Entity View\tN", ID_VIEW_ENTITY + MENUITEM SEPARATOR + MENUITEM "&Center\tEnd", ID_VIEW_CENTER + MENUITEM "&Up Floor\tPage Up", ID_VIEW_UPFLOOR + MENUITEM "&Down Floor\tPage Down", ID_VIEW_DOWNFLOOR + MENUITEM SEPARATOR + MENUITEM "&XY 100%", ID_VIEW_100 + MENUITEM "XY Zoom &In\tDelete", ID_VIEW_ZOOMIN + MENUITEM "XY Zoom &Out\tInsert", ID_VIEW_ZOOMOUT + MENUITEM SEPARATOR + MENUITEM "Show &Names", ID_VIEW_SHOWNAMES, CHECKED + MENUITEM "Show Blocks", ID_VIEW_SHOWBLOCKS + MENUITEM "Show C&oordinates", ID_VIEW_SHOWCOORDINATES + , CHECKED + MENUITEM "Show &Entities", ID_VIEW_SHOWENT, CHECKED + MENUITEM "Show &Path", ID_VIEW_SHOWPATH, CHECKED + MENUITEM "Show &Lights", ID_VIEW_SHOWLIGHTS, CHECKED + MENUITEM "Show &Water", ID_VIEW_SHOWWATER, CHECKED + MENUITEM "Show Clip &Brush", ID_VIEW_SHOWCLIP, CHECKED + MENUITEM "Show Wor&ld", ID_VIEW_SHOWWORLD, CHECKED + MENUITEM "Show Detail\tctrl-D", ID_VIEW_SHOWDETAIL, CHECKED + MENUITEM SEPARATOR + MENUITEM "&Z 100%", ID_VIEW_Z100 + MENUITEM "Z Zoo&m In\tctrl-Delete", ID_VIEW_ZZOOMIN + MENUITEM "Z Zoom O&ut\tctrl-Insert", ID_VIEW_ZZOOMOUT + END + POPUP "&Selection" + BEGIN + MENUITEM "Drag &Edges\tE", ID_SELECTION_DRAGEDGES + MENUITEM "Drag &Vertecies\tV", ID_SELECTION_DRAGVERTECIES + MENUITEM "&Clone\tspace", ID_SELECTION_CLONE + MENUITEM "Deselect\tEsc", ID_SELECTION_DESELECT + MENUITEM "&Delete\tBackspace", ID_SELECTION_DELETE + MENUITEM "Flip &X", ID_BRUSH_FLIPX + MENUITEM "Flip &Y", ID_BRUSH_FLIPY + MENUITEM "Flip &Z", ID_BRUSH_FLIPZ + MENUITEM "Rotate X", ID_BRUSH_ROTATEX + MENUITEM "Rotate Y", ID_BRUSH_ROTATEY + MENUITEM "Rotate Z", ID_BRUSH_ROTATEZ + MENUITEM "Arbitrary rotation", ID_SELECTION_ARBITRARYROTATION + + MENUITEM "Make &Hollow", ID_SELECTION_MAKEHOLLOW + MENUITEM "CSG &Subtract", ID_SELECTION_CSGSUBTRACT + MENUITEM "Select Complete &Tall", ID_SELECTION_SELECTCOMPLETETALL + + MENUITEM "Select T&ouching", ID_SELECTION_SELECTTOUCHING + MENUITEM "Select &Partial Tall", ID_SELECTION_SELECTPARTIALTALL + + MENUITEM "Select &Inside", ID_SELECTION_SELECTINSIDE + MENUITEM "Connect entities\tCtrl-k", ID_SELECTION_CONNECT + MENUITEM "Ungroup entity", ID_SELECTION_UNGROUPENTITY + MENUITEM "Make detail\tCtrl-m", ID_SELECTION_MAKE_DETAIL + MENUITEM "Make structural", ID_SELECTION_MAKE_STRUCTURAL + END + POPUP "&Bsp" + BEGIN + MENUITEM SEPARATOR + END + POPUP "&Grid" + BEGIN + MENUITEM "Grid1\t&1", ID_GRID_1 + MENUITEM "Grid2\t&2", ID_GRID_2 + MENUITEM "Grid4\t&3", ID_GRID_4 + MENUITEM "Grid8\t&4", ID_GRID_8, CHECKED + MENUITEM "Grid16\t&5", ID_GRID_16 + MENUITEM "Grid32\t&6", ID_GRID_32 + MENUITEM "Grid64\t&7", ID_GRID_64 + END + POPUP "&Textures" + BEGIN + MENUITEM "Show In &Use\tU", ID_TEXTURES_SHOWINUSE + MENUITEM "&Surface inspector\tS", ID_TEXTURES_INSPECTOR + MENUITEM SEPARATOR + MENUITEM "&Wireframe", ID_TEXTURES_WIREFRAME + MENUITEM "&Flat shade", ID_TEXTURES_FLATSHADE + MENUITEM "&Nearest", ID_VIEW_NEAREST + MENUITEM "Nearest &Mipmap", ID_VIEW_NEARESTMIPMAP + MENUITEM "&Linear", ID_VIEW_LINEAR + MENUITEM "&Bilinear", ID_VIEW_BILINEAR + MENUITEM "B&ilinear Mipmap", ID_VIEW_BILINEARMIPMAP + MENUITEM "T&rilinear", ID_VIEW_TRILINEAR + MENUITEM SEPARATOR + END + POPUP "&Misc" + BEGIN + MENUITEM "&Benchmark", ID_MISC_BENCHMARK + POPUP "&Colors" + BEGIN + MENUITEM "&Texture Background", ID_TEXTUREBK + MENUITEM "Grid Background", ID_COLORS_XYBK + MENUITEM "Grid Major", ID_COLORS_MAJOR + MENUITEM "Grid Minor", ID_COLORS_MINOR + END + MENUITEM "&Gamma", ID_MISC_GAMMA + MENUITEM "Find brush", ID_MISC_FINDBRUSH + MENUITEM "Next leak spot\tctrl-l", ID_MISC_NEXTLEAKSPOT + MENUITEM "Previous leak spot\tctrl-p", ID_MISC_PREVIOUSLEAKSPOT + MENUITEM "&Print XY View", ID_MISC_PRINTXY + MENUITEM "&Select Entity Color\tK", ID_MISC_SELECTENTITYCOLOR + END + POPUP "&Region" + BEGIN + MENUITEM "&Off", ID_REGION_OFF + MENUITEM "&Set XY", ID_REGION_SETXY + MENUITEM "Set &Tall Brush", ID_REGION_SETTALLBRUSH + MENUITEM "Set &Brush", ID_REGION_SETBRUSH + MENUITEM "Set Se&lected Brushes", ID_REGION_SETSELECTION + END + POPUP "&Brush" + BEGIN + MENUITEM "3 sided\tctrl-3", ID_BRUSH_3SIDED + MENUITEM "4 sided\tctrl-4", ID_BRUSH_4SIDED + MENUITEM "5 sided\tctrl-5", ID_BRUSH_5SIDED + MENUITEM "6 sided\tctrl-6", ID_BRUSH_6SIDED + MENUITEM "7 sided\tctrl-7", ID_BRUSH_7SIDED + MENUITEM "8 sided\tctrl-8", ID_BRUSH_8SIDED + MENUITEM "9 sided\tctrl-9", ID_BRUSH_9SIDED + MENUITEM "Arbitrary sided", ID_BRUSH_ARBITRARYSIDED + END + POPUP "&Help" + BEGIN + MENUITEM "&About", ID_HELP_ABOUT + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_FINDTEXTURE DIALOG DISCARDABLE 0, 0, 129, 53 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Find Texture" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,10,30,50,14 + PUSHBUTTON "Cancel",IDCANCEL,70,30,50,14 + EDITTEXT IDC_EDIT1,10,10,110,14,ES_AUTOHSCROLL +END + +IDD_ENTITY DIALOGEX 0, 0, 234, 389 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | + WS_CAPTION | WS_THICKFRAME +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE +CAPTION "Entity" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + LISTBOX IDC_E_LIST,5,5,180,99,LBS_SORT | LBS_NOINTEGRALHEIGHT | + LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP, + WS_EX_CLIENTEDGE + EDITTEXT IDC_E_COMMENT,5,106,180,50,ES_MULTILINE | ES_READONLY | + WS_VSCROLL,WS_EX_CLIENTEDGE + PUSHBUTTON "135",IDC_E_135,5,290,15,15 + PUSHBUTTON "180",IDC_E_180,5,305,15,15 + PUSHBUTTON "225",IDC_E_225,5,320,15,15 + PUSHBUTTON "270",IDC_E_270,21,320,15,15 + PUSHBUTTON "90",IDC_E_90,21,290,15,15 + PUSHBUTTON "45",IDC_E_45,35,290,15,15 + PUSHBUTTON "0",IDC_E_0,35,305,15,15 + PUSHBUTTON "315",IDC_E_315,35,320,15,15 + PUSHBUTTON "Up",IDC_E_UP,60,295,15,15 + PUSHBUTTON "Dn",IDC_E_DOWN,60,310,15,15 + CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,160,50,8 + CONTROL "",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,170,50,8 + CONTROL "",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,180,50,8 + CONTROL "",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,5,190,50,8 + CONTROL "",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,160,50,8 + CONTROL "",IDC_CHECK6,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,170,50,8 + CONTROL "",IDC_CHECK7,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,180,50,8 + CONTROL "",IDC_CHECK8,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,65,190,50,8 + CONTROL "!Easy",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 125,160,50,8 + CONTROL "!Medium",IDC_CHECK10,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,125,170,50,8 + CONTROL "!Hard",IDC_CHECK11,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,125,180,50,10 + CONTROL "!DeathMatch",IDC_CHECK12,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,125,190,55,10 + LISTBOX IDC_E_PROPS,5,205,180,50,LBS_SORT | LBS_USETABSTOPS | + LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT | + WS_VSCROLL | WS_TABSTOP,WS_EX_CLIENTEDGE + PUSHBUTTON "Del Key/Pair",IDC_E_DELPROP,105,295,45,15 + EDITTEXT IDC_E_STATUS,83,312,95,30,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL + LTEXT "Key",IDC_STATIC_KEY,5,260,25,10 + LTEXT "Value",IDC_STATIC_VALUE,5,275,25,10 + EDITTEXT IDC_E_KEY_FIELD,40,260,135,14,ES_AUTOHSCROLL + EDITTEXT IDC_E_VALUE_FIELD,40,275,135,14,ES_AUTOHSCROLL +END + +IDD_GAMMA DIALOGEX 0, 0, 127, 76 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Gamma" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,10,40,50,14 + PUSHBUTTON "Cancel",IDCANCEL,65,40,50,14 + EDITTEXT IDC_G_EDIT,30,15,66,13,ES_AUTOHSCROLL,WS_EX_CLIENTEDGE +END + +IDD_FINDBRUSH DIALOGEX 0, 0, 127, 76 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Find brush" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,5,55,50,14 + PUSHBUTTON "Cancel",IDCANCEL,65,55,50,14 + EDITTEXT IDC_FIND_ENTITY,80,15,46,13,ES_AUTOHSCROLL, + WS_EX_CLIENTEDGE + EDITTEXT IDC_FIND_BRUSH,80,30,46,13,ES_AUTOHSCROLL, + WS_EX_CLIENTEDGE + LTEXT "Entity number",IDC_STATIC,10,15,60,8 + LTEXT "Brush number",IDC_STATIC,10,30,65,8 +END + +IDD_ROTATE DIALOG DISCARDABLE 0, 0, 186, 71 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Arbitrary rotation" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + EDITTEXT IDC_ROTX,30,5,40,14,ES_AUTOHSCROLL + LTEXT "x",IDC_STATIC,5,10,8,8 + EDITTEXT IDC_ROTZ,30,45,40,14,ES_AUTOHSCROLL + LTEXT "y",IDC_STATIC,5,25,8,8 + EDITTEXT IDC_ROTY,30,25,40,14,ES_AUTOHSCROLL + LTEXT "z",IDC_STATIC,5,45,8,8 +END + +IDD_SIDES DIALOG DISCARDABLE 0, 0, 186, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Arbitrrary sides" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + EDITTEXT IDC_SIDES,50,15,40,14,ES_AUTOHSCROLL + LTEXT "Sides",IDC_STATIC,15,15,18,8 +END + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 274, 212 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About QuakeEd" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,217,7,50,14 + CONTROL 127,IDC_STATIC,"Static",SS_BITMAP,7,7,83,58 + CONTROL "QuakeEd 4.0(beta)\nCopyright (C) 1997 id Software, Inc.", + IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,100,10, + 110,23 + GROUPBOX "OpenGL Properties",IDC_STATIC,5,75,265,50 + LTEXT "Vendor:\t\tWHOEVER",IDC_ABOUT_GLVENDOR,10,90,125,10 + LTEXT "Version:\t\t1.1",IDC_ABOUT_GLVERSION,10,100,125,10 + LTEXT "Renderer:\tWHATEVER",IDC_ABOUT_GLRENDERER,10,110,125,10 + LTEXT "WHATEVER",IDC_ABOUT_GLEXTENSIONS,10,140,255,60 + GROUPBOX "OpenGL Extensions",IDC_STATIC,5,130,265,80 +END + +IDD_SURFACE DIALOG DISCARDABLE 400, 100, 392, 181 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Surface inspector" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,5,155,40,14 + PUSHBUTTON "Cancel",IDCANCEL,105,155,40,14 + EDITTEXT IDC_HSHIFT,85,45,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_HSHIFTA,120,45,10,15,SBS_VERT + LTEXT "Horizontal shift",IDC_STATIC,10,45,65,8 + LTEXT "Vertical shift",IDC_STATIC,10,60,65,8 + LTEXT "Horizontal stretch",IDC_STATIC,10,75,65,8 + LTEXT "Vertical stretch",IDC_STATIC,10,90,65,8 + LTEXT "Rotate",IDC_STATIC,10,105,65,8 + LTEXT "value",IDC_STATIC,10,120,65,8 + EDITTEXT IDC_VSHIFT,85,60,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_VSHIFTA,120,60,10,15,SBS_VERT + EDITTEXT IDC_HSCALE,85,75,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_HSCALEA,120,75,10,15,SBS_VERT + EDITTEXT IDC_VSCALE,85,90,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_VSCALEA,120,90,10,15,SBS_VERT + EDITTEXT IDC_ROTATE,85,105,35,15,ES_AUTOHSCROLL + SCROLLBAR IDC_ROTATEA,120,105,10,15,SBS_VERT + EDITTEXT IDC_VALUE,85,120,35,15,ES_AUTOHSCROLL + EDITTEXT IDC_TEXTURE,50,15,80,14,ES_AUTOHSCROLL + CONTROL "light",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,10,41,8 + CONTROL "slick",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,20,41,8 + CONTROL "sky",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,30,41,8 + CONTROL "warp",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,40,41,8 + CONTROL "trans33",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,50,41,8 + CONTROL "trans66",IDC_CHECK6,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,60,41,8 + CONTROL "flowing",IDC_CHECK7,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,70,41,8 + CONTROL "nodraw",IDC_CHECK8,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,160,80,41,8 + CONTROL "100",IDC_CHECK9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,90,41,8 + CONTROL "200",IDC_CHECK10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,100,41,8 + CONTROL "400",IDC_CHECK11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,110,41,8 + CONTROL "800",IDC_CHECK12,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,120,41,8 + CONTROL "1000",IDC_CHECK13,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,130,41,8 + CONTROL "2000",IDC_CHECK14,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,140,41,8 + CONTROL "4000",IDC_CHECK15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,150,41,8 + CONTROL "8000",IDC_CHECK16,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 160,160,41,8 + LTEXT "Texture",IDC_STATIC,10,18,30,8 + PUSHBUTTON "Apply",IDAPPLY,55,155,40,14 + CONTROL "10000",IDC_CHECK17,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,10,41,8 + CONTROL "20000",IDC_CHECK18,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,20,41,8 + CONTROL "40000",IDC_CHECK19,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,30,41,8 + CONTROL "80000",IDC_CHECK20,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,40,41,8 + CONTROL "100000",IDC_CHECK21,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,50,41,8 + CONTROL "200000",IDC_CHECK22,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,60,41,8 + CONTROL "400000",IDC_CHECK23,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,70,41,8 + CONTROL "800000",IDC_CHECK24,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,80,41,8 + CONTROL "1000000",IDC_CHECK25,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,90,41,8 + CONTROL "2000000",IDC_CHECK26,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,100,41,8 + CONTROL "4000000",IDC_CHECK27,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,110,41,8 + CONTROL "8000000",IDC_CHECK28,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,120,41,8 + CONTROL "10000000",IDC_CHECK29,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,130,40,8 + CONTROL "20000000",IDC_CHECK30,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,140,45,8 + CONTROL "40000000",IDC_CHECK31,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,150,45,8 + CONTROL "80000000",IDC_CHECK32,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,210,160,45,8 + CONTROL "solid",IDC_CHECK33,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,10,41,8 + CONTROL "window",IDC_CHECK34,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,20,41,8 + CONTROL "aux",IDC_CHECK35,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,31,41,8 + CONTROL "lava",IDC_CHECK36,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,41,41,8 + CONTROL "slime",IDC_CHECK37,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,50,41,8 + CONTROL "water",IDC_CHECK38,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,280,60,41,8 + CONTROL "mist",IDC_CHECK39,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,71,41,8 + CONTROL "80",IDC_CHECK40,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,81,41,8 + CONTROL "100",IDC_CHECK41,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,90,41,8 + CONTROL "200",IDC_CHECK42,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,100,41,8 + CONTROL "400",IDC_CHECK43,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,111,41,8 + CONTROL "800",IDC_CHECK44,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,121,41,8 + CONTROL "1000",IDC_CHECK45,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,130,41,8 + CONTROL "2000",IDC_CHECK46,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,140,41,8 + CONTROL "4000",IDC_CHECK47,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,151,41,8 + CONTROL "8000",IDC_CHECK48,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 280,161,41,8 + CONTROL "playerclip",IDC_CHECK49,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,10,41,8 + CONTROL "monsterclip",IDC_CHECK50,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,20,50,8 + CONTROL "current_0",IDC_CHECK51,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,31,50,8 + CONTROL "current_90",IDC_CHECK52,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,41,50,8 + CONTROL "current_180",IDC_CHECK53,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,50,50,8 + CONTROL "current_270",IDC_CHECK54,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,60,50,8 + CONTROL "current_up",IDC_CHECK55,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,71,50,8 + CONTROL "current_dn",IDC_CHECK56,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,81,50,8 + CONTROL "origin",IDC_CHECK57,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,90,41,8 + CONTROL "monster",IDC_CHECK58,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,100,41,8 + CONTROL "corpse",IDC_CHECK59,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,111,41,8 + CONTROL "detail",IDC_CHECK60,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,121,41,8 + CONTROL "translucent",IDC_CHECK61,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,130,50,8 + CONTROL "ladder",IDC_CHECK62,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,140,45,8 + CONTROL "40000000",IDC_CHECK63,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,151,45,8 + CONTROL "80000000",IDC_CHECK64,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,330,161,45,8 + GROUPBOX "Surf flags",IDC_STATIC,150,0,115,175 + GROUPBOX "Content flags",IDC_STATIC,270,0,115,175 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Id Software\0" + VALUE "FileDescription", "qe3\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "qe3\0" + VALUE "LegalCopyright", "Copyright © 1996\0" + VALUE "OriginalFilename", "qe3.exe\0" + VALUE "ProductName", "Id Software qe3\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + "3", ID_BRUSH_3SIDED, VIRTKEY, CONTROL, NOINVERT + "4", ID_BRUSH_4SIDED, VIRTKEY, CONTROL, NOINVERT + "5", ID_BRUSH_5SIDED, VIRTKEY, CONTROL, NOINVERT + "6", ID_BRUSH_6SIDED, VIRTKEY, CONTROL, NOINVERT + "7", ID_BRUSH_7SIDED, VIRTKEY, CONTROL, NOINVERT + "8", ID_BRUSH_8SIDED, VIRTKEY, CONTROL, NOINVERT + "9", ID_BRUSH_9SIDED, VIRTKEY, CONTROL, NOINVERT + "D", ID_VIEW_SHOWDETAIL, VIRTKEY, CONTROL, NOINVERT + "K", ID_SELECTION_CONNECT, VIRTKEY, CONTROL, NOINVERT + "L", ID_MISC_NEXTLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "M", ID_SELECTION_MAKE_DETAIL, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "P", ID_MISC_PREVIOUSLEAKSPOT, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_VIEW_ZZOOMIN, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, ID_VIEW_ZZOOMOUT, VIRTKEY, CONTROL, NOINVERT + "X", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_TOOLBAR1 TOOLBAR DISCARDABLE 16, 15 +BEGIN + BUTTON ID_BRUSH_FLIPX + BUTTON ID_BRUSH_ROTATEX + BUTTON ID_BRUSH_FLIPY + BUTTON ID_BRUSH_ROTATEY + BUTTON ID_BRUSH_FLIPZ + BUTTON ID_BRUSH_ROTATEZ + BUTTON ID_SELECTION_SELECTCOMPLETETALL + BUTTON ID_SELECTION_SELECTTOUCHING + BUTTON ID_SELECTION_SELECTPARTIALTALL + BUTTON ID_SELECTION_SELECTINSIDE + BUTTON ID_SELECTION_CSGSUBTRACT + BUTTON ID_SELECTION_MAKEHOLLOW + BUTTON ID_TEXTURES_WIREFRAME + BUTTON ID_TEXTURES_FLATSHADE + BUTTON ID_VIEW_TRILINEAR +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_TOOLBAR1 BITMAP DISCARDABLE "toolbar1.bmp" +IDB_BITMAP1 BITMAP DISCARDABLE "q.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ENTITY, DIALOG + BEGIN + RIGHTMARGIN, 227 + BOTTOMMARGIN, 387 + END + + IDD_GAMMA, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 120 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END + + IDD_FINDBRUSH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 120 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END + + IDD_ROTATE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + + IDD_SIDES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 48 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 267 + TOPMARGIN, 7 + BOTTOMMARGIN, 205 + END + + IDD_SURFACE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 385 + TOPMARGIN, 7 + BOTTOMMARGIN, 174 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "icon1.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/tools/quake2/extra/qe4/win_xy.c b/tools/quake2/extra/qe4/win_xy.c new file mode 100644 index 00000000..75a03444 --- /dev/null +++ b/tools/quake2/extra/qe4/win_xy.c @@ -0,0 +1,306 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// win_xy.c -- windows specific xy view code + +#include "qe3.h" + +static HDC s_hdcXY; +static HGLRC s_hglrcXY; + +static unsigned s_stipple[32] = +{ + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, + 0xaaaaaaaa, 0x55555555,0xaaaaaaaa, 0x55555555, +}; + +/* +============ +WXY_WndProc +============ +*/ +LONG WINAPI WXY_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + int fwKeys, xPos, yPos; + RECT rect; + + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_CREATE: + + s_hdcXY = GetDC(hWnd); + + QEW_SetupPixelFormat(s_hdcXY, false); + + if ( ( s_hglrcXY = wglCreateContext( s_hdcXY ) ) == 0 ) + Error( "wglCreateContext in WXY_WndProc failed" ); + + if (!wglMakeCurrent( s_hdcXY, s_hglrcXY )) + Error ("wglMakeCurrent failed"); + + if (!wglShareLists( g_qeglobals.d_hglrcBase, s_hglrcXY ) ) + Error( "wglShareLists in WXY_WndProc failed" ); + + glPolygonStipple ((char *)s_stipple); + glLineStipple (3, 0xaaaa); + + return 0; + + case WM_DESTROY: + QEW_StopGL( hWnd, s_hglrcXY, s_hdcXY ); + return 0; + + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hWnd, &ps); + + if (!wglMakeCurrent( s_hdcXY, s_hglrcXY )) + Error ("wglMakeCurrent failed"); + + QE_CheckOpenGLForErrors(); + XY_Draw (); + QE_CheckOpenGLForErrors(); + + SwapBuffers(s_hdcXY); + + EndPaint(hWnd, &ps); + } + return 0; + + case WM_KEYDOWN: + return QE_KeyDown (wParam); + + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + if ( GetTopWindow( g_qeglobals.d_hwndMain ) != hWnd) + BringWindowToTop(hWnd); + SetFocus( g_qeglobals.d_hwndXY ); + SetCapture( g_qeglobals.d_hwndXY ); + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + XY_MouseDown (xPos, yPos, fwKeys); + return 0; + + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONUP: + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + XY_MouseUp (xPos, yPos, fwKeys); + if (! (fwKeys & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); + return 0; + + case WM_MOUSEMOVE: + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + XY_MouseMoved (xPos, yPos, fwKeys); + return 0; + + case WM_SIZE: + g_qeglobals.d_xy.width = rect.right; + g_qeglobals.d_xy.height = rect.bottom; + InvalidateRect( g_qeglobals.d_hwndXY, NULL, false); + return 0; + + case WM_NCCALCSIZE:// don't let windows copy pixels + DefWindowProc (hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + + case WM_KILLFOCUS: + case WM_SETFOCUS: + SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 ); + return 0; + + case WM_CLOSE: + DestroyWindow (hWnd); + return 0; + } + + return DefWindowProc (hWnd, uMsg, wParam, lParam); +} + + +/* +============== +WXY_Create +============== +*/ +void WXY_Create (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WXY_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; //(HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = XY_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Error ("RegisterClass: failed"); + + g_qeglobals.d_hwndXY = CreateWindow (XY_WINDOW_CLASS , + "XY View", + QE3_STYLE , + ZWIN_WIDTH, + (int)(screen_height*CWIN_SIZE)-20, + screen_width-ZWIN_WIDTH, + (int)(screen_height*(1.0-CWIN_SIZE)-38), // size + + g_qeglobals.d_hwndMain, // parent + 0, // no menu + hInstance, + NULL); + + if (!g_qeglobals.d_hwndXY ) + Error ("Couldn't create XY View"); + + LoadWindowState(g_qeglobals.d_hwndXY, "xywindow"); + ShowWindow(g_qeglobals.d_hwndXY, SW_SHOWDEFAULT); +} + +static void WXY_InitPixelFormat( PIXELFORMATDESCRIPTOR *pPFD ) +{ + memset( pPFD, 0, sizeof( *pPFD ) ); + + pPFD->nSize = sizeof( PIXELFORMATDESCRIPTOR ); + pPFD->nVersion = 1; + pPFD->dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + pPFD->iPixelType = PFD_TYPE_RGBA; + pPFD->cColorBits = 24; + pPFD->cDepthBits = 32; + pPFD->iLayerType = PFD_MAIN_PLANE; + +} + +void WXY_Print( void ) +{ + DOCINFO di; + + PRINTDLG pd; + + /* + ** initialize the PRINTDLG struct and execute it + */ + memset( &pd, 0, sizeof( pd ) ); + pd.lStructSize = sizeof( pd ); + pd.hwndOwner = g_qeglobals.d_hwndXY; + pd.Flags = PD_RETURNDC; + pd.hInstance = 0; + if ( !PrintDlg( &pd ) || !pd.hDC ) + { + MessageBox( g_qeglobals.d_hwndMain, "Could not PrintDlg()", "QE4 Print Error", MB_OK | MB_ICONERROR ); + return; + } + + /* + ** StartDoc + */ + memset( &di, 0, sizeof( di ) ); + di.cbSize = sizeof( di ); + di.lpszDocName = "QE4"; + if ( StartDoc( pd.hDC, &di ) <= 0 ) + { + MessageBox( g_qeglobals.d_hwndMain, "Could not StartDoc()", "QE4 Print Error", MB_OK | MB_ICONERROR ); + return; + } + + /* + ** StartPage + */ + if ( StartPage( pd.hDC ) <= 0 ) + { + MessageBox( g_qeglobals.d_hwndMain, "Could not StartPage()", "QE4 Print Error", MB_OK | MB_ICONERROR ); + return; + } + + /* + ** read pixels from the XY window + */ + { + int bmwidth = 320, bmheight = 320; + int pwidth, pheight; + + RECT r; + + GetWindowRect( g_qeglobals.d_hwndXY, &r ); + + bmwidth = r.right - r.left; + bmheight = r.bottom - r.top; + + pwidth = GetDeviceCaps( pd.hDC, PHYSICALWIDTH ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETX ); + pheight = GetDeviceCaps( pd.hDC, PHYSICALHEIGHT ) - GetDeviceCaps( pd.hDC, PHYSICALOFFSETY ); + + StretchBlt( pd.hDC, + 0, 0, + pwidth, pheight, + s_hdcXY, + 0, 0, + bmwidth, bmheight, + SRCCOPY ); + } + + /* + ** EndPage and EndDoc + */ + if ( EndPage( pd.hDC ) <= 0 ) + { + MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndPage()", MB_OK | MB_ICONERROR ); + return; + } + + if ( EndDoc( pd.hDC ) <= 0 ) + { + MessageBox( g_qeglobals.d_hwndMain, "QE4 Print Error", "Could not EndDoc()", MB_OK | MB_ICONERROR ); + return; + } +} diff --git a/tools/quake2/extra/qe4/win_z.c b/tools/quake2/extra/qe4/win_z.c new file mode 100644 index 00000000..a7233c8c --- /dev/null +++ b/tools/quake2/extra/qe4/win_z.c @@ -0,0 +1,195 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// win_cam.c -- windows specific camera view code + +#include "qe3.h" + +static HDC s_hdcZ; +static HGLRC s_hglrcZ; + +/* +============ +WZ_WndProc +============ +*/ +LONG WINAPI WZ_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + int fwKeys, xPos, yPos; + RECT rect; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + + case WM_DESTROY: + QEW_StopGL( hWnd, s_hglrcZ, s_hdcZ ); + return 0; + + case WM_CREATE: + s_hdcZ = GetDC(hWnd); + QEW_SetupPixelFormat( s_hdcZ, false); + if ( ( s_hglrcZ = wglCreateContext( s_hdcZ ) ) == 0 ) + Error( "wglCreateContext in WZ_WndProc failed" ); + + if (!wglMakeCurrent( s_hdcZ, s_hglrcZ )) + Error ("wglMakeCurrent in WZ_WndProc failed"); + + if (!wglShareLists( g_qeglobals.d_hglrcBase, s_hglrcZ ) ) + Error( "wglShareLists in WZ_WndProc failed" ); + return 0; + + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hWnd, &ps); + + if ( !wglMakeCurrent( s_hdcZ, s_hglrcZ ) ) + Error ("wglMakeCurrent failed"); + QE_CheckOpenGLForErrors(); + + Z_Draw (); + SwapBuffers(s_hdcZ); + + EndPaint(hWnd, &ps); + } + return 0; + + + case WM_KEYDOWN: + QE_KeyDown (wParam); + return 0; + + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + if (GetTopWindow(g_qeglobals.d_hwndMain) != hWnd) + BringWindowToTop(hWnd); + + SetFocus( g_qeglobals.d_hwndZ ); + SetCapture( g_qeglobals.d_hwndZ ); + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + Z_MouseDown (xPos, yPos, fwKeys); + return 0; + + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONUP: + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + Z_MouseUp (xPos, yPos, fwKeys); + if (! (fwKeys & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); + return 0; + + case WM_GETMINMAXINFO: + { + MINMAXINFO *pmmi = (LPMINMAXINFO) lParam; + + pmmi->ptMinTrackSize.x = ZWIN_WIDTH; + return 0; + } + + case WM_MOUSEMOVE: + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + Z_MouseMoved (xPos, yPos, fwKeys); + return 0; + + case WM_SIZE: + z.width = rect.right; + z.height = rect.bottom; + InvalidateRect( g_qeglobals.d_hwndZ, NULL, false); + return 0; + + case WM_NCCALCSIZE:// don't let windows copy pixels + DefWindowProc (hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + + case WM_KILLFOCUS: + case WM_SETFOCUS: + SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 ); + return 0; + + case WM_CLOSE: + /* call destroy window to cleanup and go away */ + DestroyWindow (hWnd); + return 0; + } + + return DefWindowProc (hWnd, uMsg, wParam, lParam); +} + + +/* +============== +WZ_Create +============== +*/ +void WZ_Create (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WZ_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = Z_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Error ("WCam_Register: failed"); + + g_qeglobals.d_hwndZ = CreateWindow (Z_WINDOW_CLASS , + "Z", + QE3_STYLE, + 0,20,ZWIN_WIDTH,screen_height-38, // size + g_qeglobals.d_hwndMain, // parent + 0, // no menu + hInstance, + NULL); + if (!g_qeglobals.d_hwndZ) + Error ("Couldn't create zwindow"); + + LoadWindowState(g_qeglobals.d_hwndZ, "zwindow"); + ShowWindow (g_qeglobals.d_hwndZ, SW_SHOWDEFAULT); +} diff --git a/tools/quake2/extra/qe4/xy.c b/tools/quake2/extra/qe4/xy.c new file mode 100644 index 00000000..5c8303e6 --- /dev/null +++ b/tools/quake2/extra/qe4/xy.c @@ -0,0 +1,973 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qe3.h" + +#define PAGEFLIPS 2 + +/* +============ +XY_Init +============ +*/ +void XY_Init (void) +{ + g_qeglobals.d_xy.origin[0] = 0; + g_qeglobals.d_xy.origin[1] = 20; + g_qeglobals.d_xy.origin[2] = 46; + + g_qeglobals.d_xy.scale = 1; +} + + +/* +============================================================================ + + MOUSE ACTIONS + +============================================================================ +*/ + +static int cursorx, cursory; +static int buttonstate; +static int pressx, pressy; +static vec3_t pressdelta; +static qboolean press_selection; + +void XY_ToPoint (int x, int y, vec3_t point) +{ + point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale; + point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale; + point[2] = 0; +} + +void XY_ToGridPoint (int x, int y, vec3_t point) +{ + point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale; + point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale; + point[2] = 0; + point[0] = floor(point[0]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + point[1] = floor(point[1]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; +} + +/* +============== +XY_MouseDown +============== +*/ +void XY_MouseDown (int x, int y, int buttons) +{ + vec3_t point; + vec3_t origin, dir, right, up; + + buttonstate = buttons; + pressx = x; + pressy = y; + VectorCopy (vec3_origin, pressdelta); + + XY_ToPoint (x, y, point); + + VectorCopy (point, origin); + origin[2] = 8192; + + dir[0] = 0; dir[1] = 0; dir[2] = -1; + right[0] = 1/g_qeglobals.d_xy.scale; right[1] = 0; right[2] = 0; + up[0] = 0; up[1] = 1/g_qeglobals.d_xy.scale; up[2] = 0; + + press_selection = (selected_brushes.next != &selected_brushes); + + Sys_GetCursorPos (&cursorx, &cursory); + + // lbutton = manipulate selection + // shift-LBUTTON = select + if ( (buttons == MK_LBUTTON) + || (buttons == (MK_LBUTTON | MK_SHIFT)) + || (buttons == (MK_LBUTTON | MK_CONTROL)) + || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) ) + { + Drag_Begin (x, y, buttons, + right, up, + origin, dir); + return; + } + + // control mbutton = move camera + if (buttonstate == (MK_CONTROL|MK_MBUTTON) ) + { + camera.origin[0] = point[0]; + camera.origin[1] = point[1]; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + } + + // mbutton = angle camera + if (buttonstate == MK_MBUTTON) + { + VectorSubtract (point, camera.origin, point); + if (point[1] || point[0]) + { + camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]); + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY); + } + } + + // shift mbutton = move z checker + if (buttonstate == (MK_SHIFT|MK_MBUTTON) ) + { + XY_ToPoint (x, y, point); + z.origin[0] = point[0]; + z.origin[1] = point[1]; + Sys_UpdateWindows (W_XY_OVERLAY|W_Z); + return; + } + +} + +/* +============== +XY_MouseUp +============== +*/ +void XY_MouseUp (int x, int y, int buttons) +{ + Drag_MouseUp (); + + if (!press_selection) + Sys_UpdateWindows (W_ALL); + + buttonstate = 0; +} + +qboolean DragDelta (int x, int y, vec3_t move) +{ + vec3_t xvec, yvec, delta; + int i; + + xvec[0] = 1/g_qeglobals.d_xy.scale; + xvec[1] = xvec[2] = 0; + yvec[1] = 1/g_qeglobals.d_xy.scale; + yvec[0] = yvec[2] = 0; + + for (i=0 ; i<3 ; i++) + { + delta[i] = xvec[i]*(x - pressx) + yvec[i]*(y - pressy); + delta[i] = floor(delta[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; + } + VectorSubtract (delta, pressdelta, move); + VectorCopy (delta, pressdelta); + + if (move[0] || move[1] || move[2]) + return true; + return false; +} + +/* +============== +NewBrushDrag +============== +*/ +void NewBrushDrag (int x, int y) +{ + vec3_t mins, maxs, junk; + int i; + float temp; + brush_t *n; + + if (!DragDelta (x,y, junk)) + return; + // delete the current selection + if (selected_brushes.next != &selected_brushes) + Brush_Free (selected_brushes.next); + XY_ToGridPoint (pressx, pressy, mins); + mins[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize)); + XY_ToGridPoint (x, y, maxs); + maxs[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize)); + if (maxs[2] <= mins[2]) + maxs[2] = mins[2] + g_qeglobals.d_gridsize; + + for (i=0 ; i<3 ; i++) + { + if (mins[i] == maxs[i]) + return; // don't create a degenerate brush + if (mins[i] > maxs[i]) + { + temp = mins[i]; + mins[i] = maxs[i]; + maxs[i] = temp; + } + } + + n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef); + if (!n) + return; + + Brush_AddToList (n, &selected_brushes); + + Entity_LinkBrush (world_entity, n); + + Brush_Build( n ); + +// Sys_UpdateWindows (W_ALL); + Sys_UpdateWindows (W_XY| W_CAMERA); +} + +/* +============== +XY_MouseMoved +============== +*/ +void XY_MouseMoved (int x, int y, int buttons) +{ + vec3_t point; + + if (!buttonstate) + return; + + // lbutton without selection = drag new brush + if (buttonstate == MK_LBUTTON && !press_selection) + { + NewBrushDrag (x, y); + return; + } + + // lbutton (possibly with control and or shift) + // with selection = drag selection + if (buttonstate & MK_LBUTTON) + { + Drag_MouseMoved (x, y, buttons); + Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA); + return; + } + + // control mbutton = move camera + if (buttonstate == (MK_CONTROL|MK_MBUTTON) ) + { + XY_ToPoint (x, y, point); + camera.origin[0] = point[0]; + camera.origin[1] = point[1]; + Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA); + return; + } + + // shift mbutton = move z checker + if (buttonstate == (MK_SHIFT|MK_MBUTTON) ) + { + XY_ToPoint (x, y, point); + z.origin[0] = point[0]; + z.origin[1] = point[1]; + Sys_UpdateWindows (W_XY_OVERLAY|W_Z); + return; + } + + // mbutton = angle camera + if (buttonstate == MK_MBUTTON ) + { + XY_ToPoint (x, y, point); + VectorSubtract (point, camera.origin, point); + if (point[1] || point[0]) + { + camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]); + Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA); + } + return; + } + + // rbutton = drag xy origin + if (buttonstate == MK_RBUTTON) + { + Sys_GetCursorPos (&x, &y); + if (x != cursorx || y != cursory) + { + g_qeglobals.d_xy.origin[0] -= (x-cursorx)/g_qeglobals.d_xy.scale; + g_qeglobals.d_xy.origin[1] += (y-cursory)/g_qeglobals.d_xy.scale; + Sys_SetCursorPos (cursorx, cursory); + Sys_UpdateWindows (W_XY | W_XY_OVERLAY); + } + return; + } +} + + +/* +============================================================================ + +DRAWING + +============================================================================ +*/ + + +/* +============== +XY_DrawGrid +============== +*/ +void XY_DrawGrid (void) +{ + float x, y, xb, xe, yb, ye; + int w, h; + char text[32]; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_1D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale; + h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale; + + xb = g_qeglobals.d_xy.origin[0] - w; + if (xb < region_mins[0]) + xb = region_mins[0]; + xb = 64 * floor (xb/64); + + xe = g_qeglobals.d_xy.origin[0] + w; + if (xe > region_maxs[0]) + xe = region_maxs[0]; + xe = 64 * ceil (xe/64); + + yb = g_qeglobals.d_xy.origin[1] - h; + if (yb < region_mins[1]) + yb = region_mins[1]; + yb = 64 * floor (yb/64); + + ye = g_qeglobals.d_xy.origin[1] + h; + if (ye > region_maxs[1]) + ye = region_maxs[1]; + ye = 64 * ceil (ye/64); + + // draw major blocks + + glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR]); + + if ( g_qeglobals.d_showgrid ) + { + + glBegin (GL_LINES); + + for (x=xb ; x<=xe ; x+=64) + { + glVertex2f (x, yb); + glVertex2f (x, ye); + } + for (y=yb ; y<=ye ; y+=64) + { + glVertex2f (xb, y); + glVertex2f (xe, y); + } + + glEnd (); + + } + + // draw minor blocks + if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize*g_qeglobals.d_xy.scale >= 4) + { + glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]); + + glBegin (GL_LINES); + for (x=xb ; x region_maxs[0]) + xe = region_maxs[0]; + xe = 1024 * ceil (xe/1024); + + yb = g_qeglobals.d_xy.origin[1] - h; + if (yb < region_mins[1]) + yb = region_mins[1]; + yb = 1024 * floor (yb/1024); + + ye = g_qeglobals.d_xy.origin[1] + h; + if (ye > region_maxs[1]) + ye = region_maxs[1]; + ye = 1024 * ceil (ye/1024); + + // draw major blocks + + glColor3f(0,0,1); + glLineWidth (2); + + glBegin (GL_LINES); + + for (x=xb ; x<=xe ; x+=1024) + { + glVertex2f (x, yb); + glVertex2f (x, ye); + } + for (y=yb ; y<=ye ; y+=1024) + { + glVertex2f (xb, y); + glVertex2f (xe, y); + } + + glEnd (); + glLineWidth (1); + + // draw coordinate text if needed + + for (x=xb ; xowner) + return FALSE; // during construction + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) + { + if (!strncmp(pb->brush_faces->texdef.name, "clip", 4)) + return TRUE; + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER) + { + if (pb->brush_faces->texdef.name[0] == '*') + return TRUE; + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAIL) + { + if (pb->brush_faces->texdef.contents & CONTENTS_DETAIL) + return TRUE; + } + + if (pb->owner == world_entity) + { + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) + return TRUE; + return FALSE; + } + else if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT) + return TRUE; + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS) + { + if (!strncmp(pb->owner->eclass->name, "light", 5)) + return TRUE; + } + + if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) + { + if (!strncmp(pb->owner->eclass->name, "path", 4)) + return TRUE; + } + + return FALSE; +} + +/* +============================================================= + + PATH LINES + +============================================================= +*/ + +/* +================== +DrawPathLines + +Draws connections between entities. +Needs to consider all entities, not just ones on screen, +because the lines can be visible when neither end is. +Called for both camera view and xy view. +================== +*/ +void DrawPathLines (void) +{ + int i, j, k; + vec3_t mid, mid1; + entity_t *se, *te; + brush_t *sb, *tb; + char *psz; + vec3_t dir, s1, s2; + vec_t len, f; + int arrows; + int num_entities; + char *ent_target[MAX_MAP_ENTITIES]; + entity_t *ent_entity[MAX_MAP_ENTITIES]; + + + num_entities = 0; + for (te = entities.next ; te != &entities && num_entities != MAX_MAP_ENTITIES ; te = te->next) + { + ent_target[num_entities] = ValueForKey (te, "target"); + if (ent_target[num_entities][0]) + { + ent_entity[num_entities] = te; + num_entities++; + } + } + + for (se = entities.next ; se != &entities ; se = se->next) + { + psz = ValueForKey(se, "targetname"); + + if (psz == NULL || psz[0] == '\0') + continue; + + sb = se->brushes.onext; + if (sb == &se->brushes) + continue; + + for (k=0 ; kbrushes.onext; + if (tb == &te->brushes) + continue; + + for (i=0 ; i<3 ; i++) + mid[i] = (sb->mins[i] + sb->maxs[i])*0.5; + + for (i=0 ; i<3 ; i++) + mid1[i] = (tb->mins[i] + tb->maxs[i])*0.5; + + VectorSubtract (mid1, mid, dir); + len = VectorNormalize (dir); + s1[0] = -dir[1]*8 + dir[0]*8; + s2[0] = dir[1]*8 + dir[0]*8; + s1[1] = dir[0]*8 + dir[1]*8; + s2[1] = -dir[0]*8 + dir[1]*8; + + glColor3f (se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]); + + glBegin(GL_LINES); + glVertex3fv(mid); + glVertex3fv(mid1); + + arrows = (int)(len / 256) + 1; + + for (i=0 ; inext) + { + if (brush->mins[0] > maxs[0] + || brush->mins[1] > maxs[1] + || brush->maxs[0] < mins[0] + || brush->maxs[1] < mins[1] ) + { + culled++; + continue; // off screen + } + + if (FilterBrush (brush)) + continue; + drawn++; + if (brush->owner != e) + { + e = brush->owner; + glColor3fv(e->eclass->color); + } + Brush_DrawXY( brush ); + } + + DrawPathLines (); + + // + // draw pointfile + // + if ( g_qeglobals.d_pointfile_display_list) + glCallList (g_qeglobals.d_pointfile_display_list); + + // + // draw block grid + // + if ( g_qeglobals.show_blocks) + XY_DrawBlockGrid (); + + // + // now draw selected brushes + // + glTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); + + glColor3f(1.0, 0.0, 0.0); + glEnable (GL_LINE_STIPPLE); + glLineStipple (3, 0xaaaa); + glLineWidth (2); + + for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) + { + drawn++; + Brush_DrawXY( brush ); + } + + glDisable (GL_LINE_STIPPLE); + glLineWidth (1); + + // edge / vertex flags + + if (g_qeglobals.d_select_mode == sel_vertex) + { + glPointSize (4); + glColor3f (0,1,0); + glBegin (GL_POINTS); + for (i=0 ; imins[0] + b->maxs[0])/2; + } + + dir[0] = 0; dir[1] = 1; dir[2] = 0; + + vright[0] = 0; vright[1] = 0; vright[2] = 0; + + // LBUTTON = manipulate selection + // shift-LBUTTON = select + // middle button = grab texture + // ctrl-middle button = set entire brush to texture + // ctrl-shift-middle button = set single face to texture + if ( (buttons == MK_LBUTTON) + || (buttons == (MK_LBUTTON | MK_SHIFT)) + || (buttons == MK_MBUTTON) +// || (buttons == (MK_MBUTTON|MK_CONTROL)) + || (buttons == (MK_MBUTTON|MK_SHIFT|MK_CONTROL)) ) + { + Drag_Begin (x, y, buttons, + vright, vup, + org, dir); + return; + } + + // control mbutton = move camera + if ((buttons == (MK_CONTROL|MK_MBUTTON) ) || (buttons == (MK_CONTROL|MK_LBUTTON))) + { + camera.origin[2] = org[2] ; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY|W_Z); + } + + +} + +/* +============== +Z_MouseUp +============== +*/ +void Z_MouseUp (int x, int y, int buttons) +{ + Drag_MouseUp (); +} + +/* +============== +Z_MouseMoved +============== +*/ +void Z_MouseMoved (int x, int y, int buttons) +{ + if (!buttons) + return; + if (buttons == MK_LBUTTON) + { + Drag_MouseMoved (x, y, buttons); + Sys_UpdateWindows (W_Z|W_CAMERA); + return; + } + // rbutton = drag z origin + if (buttons == MK_RBUTTON) + { + Sys_GetCursorPos (&x, &y); + if ( y != cursory) + { + z.origin[2] += y-cursory; + Sys_SetCursorPos (cursorx, cursory); + Sys_UpdateWindows (W_Z); + } + return; + } + // control mbutton = move camera + if ((buttons == (MK_CONTROL|MK_MBUTTON) ) || (buttons == (MK_CONTROL|MK_LBUTTON))) + { + camera.origin[2] = (y - (z.height/2))/z.scale; + Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY|W_Z); + } + +} + + +/* +============================================================================ + +DRAWING + +============================================================================ +*/ + + +/* +============== +Z_DrawGrid +============== +*/ +void Z_DrawGrid (void) +{ + float zz, zb, ze; + int w, h; + char text[32]; + + w = z.width/2 / z.scale; + h = z.height/2 / z.scale; + + zb = z.origin[2] - h; + if (zb < region_mins[2]) + zb = region_mins[2]; + zb = 64 * floor (zb/64); + + ze = z.origin[2] + h; + if (ze > region_maxs[2]) + ze = region_maxs[2]; + ze = 64 * ceil (ze/64); + + // draw major blocks + + glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR]); + + glBegin (GL_LINES); + + glVertex2f (0, zb); + glVertex2f (0, ze); + + for (zz=zb ; zz= 4) + { + glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]); + + glBegin (GL_LINES); + for (zz=zb ; zznext) + { + if (brush->mins[0] >= z.origin[0] + || brush->maxs[0] <= z.origin[0] + || brush->mins[1] >= z.origin[1] + || brush->maxs[1] <= z.origin[1]) + continue; + + if (!Brush_Ray (org_top, dir_down, brush, &top)) + continue; + top = org_top[2] - top; + if (!Brush_Ray (org_bottom, dir_up, brush, &bottom)) + continue; + bottom = org_bottom[2] + bottom; + + q = Texture_ForName (brush->brush_faces->texdef.name); + glColor3f (q->color[0], q->color[1], q->color[2]); + glBegin (GL_QUADS); + glVertex2f (-xCam, bottom); + glVertex2f (xCam, bottom); + glVertex2f (xCam, top); + glVertex2f (-xCam, top); + glEnd (); + + glColor3f (1,1,1); + glBegin (GL_LINE_LOOP); + glVertex2f (-xCam, bottom); + glVertex2f (xCam, bottom); + glVertex2f (xCam, top); + glVertex2f (-xCam, top); + glEnd (); + } + + // + // now draw selected brushes + // + for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) + { + if ( !(brush->mins[0] >= z.origin[0] + || brush->maxs[0] <= z.origin[0] + || brush->mins[1] >= z.origin[1] + || brush->maxs[1] <= z.origin[1]) ) + { + if (Brush_Ray (org_top, dir_down, brush, &top)) + { + top = org_top[2] - top; + if (Brush_Ray (org_bottom, dir_up, brush, &bottom)) + { + bottom = org_bottom[2] + bottom; + + q = Texture_ForName (brush->brush_faces->texdef.name); + glColor3f (q->color[0], q->color[1], q->color[2]); + glBegin (GL_QUADS); + glVertex2f (-xCam, bottom); + glVertex2f (xCam, bottom); + glVertex2f (xCam, top); + glVertex2f (-xCam, top); + glEnd (); + } + } + } + + glColor3f (1,0,0); + glBegin (GL_LINE_LOOP); + glVertex2f (-xCam, brush->mins[2]); + glVertex2f (xCam, brush->mins[2]); + glVertex2f (xCam, brush->maxs[2]); + glVertex2f (-xCam, brush->maxs[2]); + glEnd (); + } + + + ZDrawCameraIcon (); + + glFinish(); + QE_CheckOpenGLForErrors(); + + if (z.timing) + { + end = Sys_DoubleTime (); + Sys_Printf ("z: %i ms\n", (int)(1000*(end-start))); + } +} + diff --git a/tools/quake2/extra/qe4/z.h b/tools/quake2/extra/qe4/z.h new file mode 100644 index 00000000..5e3545a6 --- /dev/null +++ b/tools/quake2/extra/qe4/z.h @@ -0,0 +1,42 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +// window system independent camera view code + +typedef struct +{ + int width, height; + + qboolean timing; + + vec3_t origin; // at center of window + float scale; +} z_t; + +extern z_t z; + +void Z_Init (void); +void Z_MouseDown (int x, int y, int buttons); +void Z_MouseUp (int x, int y, int buttons); +void Z_MouseMoved (int x, int y, int buttons); +void Z_Draw (void); + diff --git a/tools/quake2/extra/texpaint/docs.txt b/tools/quake2/extra/texpaint/docs.txt new file mode 100644 index 00000000..f50759e9 --- /dev/null +++ b/tools/quake2/extra/texpaint/docs.txt @@ -0,0 +1,38 @@ + +Texpaint works with three data types: + +Skin textures +Model frames +S/T mappings + + +Skin textures can be either lbm or pcx files, and they will allways be +saved out the same size as loaded in, even if it is larger than the +active texture area. + +Model frames are alias .tri files. Adding support for 3ds would not +be difficult, but it is likely that there would be coordinate problems +unless the entire model was done completely in 3ds. + +S/T mappings allow a skin to be mapped onto any model frame. A mapping is +generated from a base frame and a texture size. If a coords.txt file is +not present, texpaint will generate a default mapping that is compatable +with the output of the old texmake. New skin or remap to skin will +generate a new coords.txt file. + + +Usage +----- +A three button mouse is required. + +The left button paints with the current color in either the skin window +or the camera window, or selects colors in the palette view. Ctrl-left +click picks up the color clicked on in any view, making it current. + +Right button dragging slides the object or skin around. Ctrl-right drag +to move in or out on the object. + +Middle button dragging rotates the object in the camera view. Ctrl-middle +drag to change the roll angle. + + diff --git a/tools/quake2/extra/texpaint/resource.h b/tools/quake2/extra/texpaint/resource.h new file mode 100644 index 00000000..7c26da1d --- /dev/null +++ b/tools/quake2/extra/texpaint/resource.h @@ -0,0 +1,58 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by texmake.rc +// +#define IDR_MENU1 101 +#define IDR_MENU2 102 +#define IDR_ACCELERATOR1 104 +#define IDD_NEWSKIN 105 +#define IDC_WIDTH 1000 +#define IDC_HEIGHT 1001 +#define ID_FILE_SAVEAS 4003 +#define ID_VIEW_MODELLINES 4006 +#define ID_VIEW_MODELLIGHTING 4008 +#define ID_FILE_OPENSKIN 4009 +#define ID_FILE_SAVESKIN 4010 +#define ID_FILE_SAVESKINAS 4011 +#define ID_FILE_EXIT 4012 +#define ID_FILE_OPENMODEL 4013 +#define ID_FILE_RELOADSKIN 4014 +#define ID_FILE_NEWSKIN 4016 +#define ID_FILE_OPENFRAME 4017 +#define ID_VIEW_SKINLINES 4018 +#define ID_VIEW_MODELINES 4019 +#define ID_VIEW_TEXTURELINES 4020 +#define ID_FILE_RESAMPLESKIN 4024 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 4025 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/tools/quake2/extra/texpaint/texmake.aps b/tools/quake2/extra/texpaint/texmake.aps new file mode 100644 index 0000000000000000000000000000000000000000..5a63f6cc81037601ec654473af83084e5fb92dea GIT binary patch literal 33472 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 Hn}h!crfN(| literal 0 HcmV?d00001 diff --git a/tools/quake2/extra/texpaint/texmake.rc b/tools/quake2/extra/texpaint/texmake.rc new file mode 100644 index 00000000..21a1eb10 --- /dev/null +++ b/tools/quake2/extra/texpaint/texmake.rc @@ -0,0 +1,156 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU2 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New skin\tCtrl-n", ID_FILE_NEWSKIN + MENUITEM "&Open skin\tCtrl-o", ID_FILE_OPENSKIN + MENUITEM "&Reload skin\tCtrl-r", ID_FILE_RELOADSKIN + MENUITEM "&Save skin\tCtrl-s", ID_FILE_SAVESKIN + MENUITEM "Save skin &as\tCtrl-a", ID_FILE_SAVESKINAS + MENUITEM "Resample skin", ID_FILE_RESAMPLESKIN + MENUITEM SEPARATOR + MENUITEM "Open &frame\tCtrl-f", ID_FILE_OPENFRAME + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Undo\tCtrl-z", ID_EDIT_UNDO + MENUITEM "&Redo\tCtrl-y", ID_EDIT_REDO + END + POPUP "&View" + BEGIN + MENUITEM "&Model lines\tCtrl-m", ID_VIEW_MODELLINES + MENUITEM "&Texture lines\tCtrl-t", ID_VIEW_TEXTURELINES + MENUITEM "Model &lighting\tCtrl-l", ID_VIEW_MODELLIGHTING + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + "A", ID_FILE_SAVESKINAS, VIRTKEY, CONTROL, NOINVERT + "F", ID_FILE_OPENFRAME, VIRTKEY, CONTROL, NOINVERT + "L", ID_VIEW_MODELLIGHTING, VIRTKEY, CONTROL, NOINVERT + "M", ID_VIEW_MODELLINES, VIRTKEY, CONTROL, NOINVERT + "N", ID_FILE_NEWSKIN, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPENSKIN, VIRTKEY, CONTROL, NOINVERT + "R", ID_FILE_RELOADSKIN, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVESKIN, VIRTKEY, CONTROL, NOINVERT + "T", ID_VIEW_TEXTURELINES, VIRTKEY, CONTROL, NOINVERT + "Y", ID_EDIT_REDO, VIRTKEY, CONTROL, NOINVERT + "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_NEWSKIN DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "New Skin" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 + EDITTEXT IDC_WIDTH,51,14,40,14,ES_AUTOHSCROLL + LTEXT "Width",IDC_STATIC,20,17,20,8 + EDITTEXT IDC_HEIGHT,51,37,40,14,ES_AUTOHSCROLL + LTEXT "height",IDC_STATIC,19,40,20,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_NEWSKIN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/tools/quake2/extra/texpaint/texpaint.c b/tools/quake2/extra/texpaint/texpaint.c new file mode 100644 index 00000000..cad7028d --- /dev/null +++ b/tools/quake2/extra/texpaint/texpaint.c @@ -0,0 +1,311 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "texpaint.h" + +triangle_t *faces; +int numfaces; + +int skinwidth, skinheight; +int picwidth, picheight; +int width, height; +int iwidth, iheight; +int width2, height2; // padded to ^2 + +float tmcoords[10000][3][2]; + +byte pic[1024*512]; +unsigned rgb[1024*512]; + +float scale; +float s_scale, t_scale; + +char filename[1024]; +char picfilename[1024]; + + +/* +================ +BoundFaces +================ +*/ +vec3_t mins, maxs; + +void BoundFaces (void) +{ + int i,j,k; + triangle_t *pol; + float v; + + for (i=0 ; i<3 ; i++) + { + mins[i] = 9999; + maxs[i] = -9999; + } + + for (i=0 ; iverts[j][k]; + if (vmaxs[k]) + maxs[k] = v; + } + } + + for (i=0 ; i<3 ; i++) + { + mins[i] = floor(mins[i]); + maxs[i] = ceil(maxs[i]); + } + + width = maxs[0] - mins[0]; + height = maxs[2] - mins[2]; + + printf ("width: %i height: %i\n",width, height); + + if (!skinwidth) + { // old way + scale = 8; + if (width*scale >= 150) + scale = 150.0 / width; + if (height*scale >= 190) + scale = 190.0 / height; + s_scale = t_scale = scale; + iwidth = ceil(width*scale) + 4; + iheight = ceil(height*scale) + 4; + } + else + { // new way + s_scale = (skinwidth/2-4)/(float)width; + t_scale = (skinheight-4)/(float)height; + iwidth = skinwidth/2; + iheight = skinheight; + } + + printf ("scale: %f\n",scale); + printf ("iwidth: %i iheight: %i\n",iwidth, iheight); +} + + + +/* +============ +AddFace +============ +*/ +void AddFace (int facenum, triangle_t *f) +{ + vec3_t v1, v2, normal; + int basex, basey; + int i, j; + int coords[3][2]; + +// +// determine which side to map the teture to +// + VectorSubtract (f->verts[0], f->verts[1], v1); + VectorSubtract (f->verts[2], f->verts[1], v2); + CrossProduct (v1, v2, normal); + + if (normal[1] > 0) + basex = iwidth + 2; + else + basex = 2; + basey = 2; + + for (i=0 ; i<3 ; i++) + { + coords[i][0] = Q_rint((f->verts[i][0] - mins[0])*s_scale + basex); + coords[i][1] = Q_rint( (maxs[2] - f->verts[i][2])*t_scale + basey); +tmcoords[facenum][i][0] = coords[i][0]/(float)width2; +tmcoords[facenum][i][1] = coords[i][1]/(float)height2; + } + +} + + +void CalcTmCoords (void) +{ + int j; + + BoundFaces (); + + for (j=0 ; j 126))) + lpCmdLine++; + + if (*lpCmdLine) + { + argv[argc] = lpCmdLine; + argc++; + + while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) + lpCmdLine++; + + if (*lpCmdLine) + { + *lpCmdLine = 0; + lpCmdLine++; + } + + } + } +} + +/* +================= +LoadTriFile +================= +*/ +void LoadTriFile (char *name) +{ + strcpy (tri_filename, name); + SetWindowText (camerawindow, tri_filename); + + LoadTriangleList (tri_filename, &faces, &numfaces); + InvalidateRect (camerawindow, NULL, false); +} + +/* +================== +TimerProc + +================== +*/ +int CALLBACK TimerProc( + HWND hwnd, // handle of window for timer messages + UINT uMsg, // WM_TIMER message + UINT idEvent, // timer identifier + DWORD dwTime // current system time + ) +{ + static int counter; + char name[1024]; + + if (!skin_filename[0]) + return 0; + + if (!modified_past_autosave) + { + counter = 0; + return 0; + } + + counter++; + + if (counter < 3*5) + return 0; // save every five minutes + + strcpy (name, skin_filename); + StripExtension (name); + strcat (name, "_autosave.lbm"); + Skin_SaveFile (name); + + modified_past_autosave = false; + counter = 0; + + return 0; +} + +/* +================== +WinMain + +================== +*/ +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance + ,LPSTR lpCmdLine, int nCmdShow) +{ + MSG msg; + HACCEL accelerators; + + main_instance = hInstance; + + ParseCommandLine (lpCmdLine); + + screen_width = GetSystemMetrics (SM_CXFULLSCREEN); + screen_height = GetSystemMetrics (SM_CYFULLSCREEN); + + // hack for broken NT 4.0 dual screen + if (screen_width > 2*screen_height) + screen_width /= 2; + + accelerators = LoadAccelerators (hInstance + , MAKEINTRESOURCE(IDR_ACCELERATOR1)); + if (!accelerators) + Sys_Error ("LoadAccelerators failed"); + + Main_Create (hInstance); + WCam_Create (hInstance); + WPal_Create (hInstance); + WSkin_Create (hInstance); + + if (argc == 2) + Skin_LoadFile (argv[1]); + + SetTimer ( mainwindow, 1, 1000*20, TimerProc ); + + while (1) + { + if (!GetMessage (&msg, mainwindow, 0, 0)) + break; + if (!TranslateAccelerator(mainwindow, accelerators, &msg) ) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + + /* return success of application */ + return TRUE; +} + diff --git a/tools/quake2/extra/texpaint/texpaint.h b/tools/quake2/extra/texpaint/texpaint.h new file mode 100644 index 00000000..15eaf9ed --- /dev/null +++ b/tools/quake2/extra/texpaint/texpaint.h @@ -0,0 +1,88 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "cmdlib.h" +#include "mathlib.h" +#include "lbmlib.h" +#include "trilib.h" +#include "l3dslib.h" + +#include +#include +#include +#include +#include "resource.h" +#include "afxres.h" + +extern HINSTANCE main_instance; + +extern HGLRC baseRC; + +extern HWND mainwindow; +extern HWND camerawindow; +extern HWND palettewindow; +extern HWND skinwindow; + +extern int screen_width, screen_height; + +#define QE3_STYLE (WS_OVERLAPPED| WS_CAPTION | WS_THICKFRAME | \ + /* WS_MINIMIZEBOX | */ WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | \ + WS_CLIPCHILDREN | WS_CHILD) + +extern byte pic[1024*512]; +extern unsigned rgb[1024*512]; +extern unsigned index_texture[1024*512]; +extern byte palette[768]; + +extern triangle_t *faces; +extern int numfaces; +extern float tmcoords[10000][3][2]; + +extern int skinwidth, skinheight; +extern int picwidth, picheight; +extern int width, height; +extern int iwidth, iheight; +extern int width2, height2; // padded to ^2 + +extern char tri_filename[1024]; +extern char skin_filename[1024]; + +extern int selected_index; +extern unsigned selected_rgb; + +extern qboolean model_lines; +extern qboolean skin_lines; + +extern qboolean modified; +extern qboolean modified_past_autosave; + +#define TEXTURE_SKIN 1 +#define TEXTURE_INDEX 2 + +#define MENU_VIEW 2 + +#define MODEL_DISPLAYLIST 1 + +typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint); + +extern BINDTEXFUNCPTR BindTextureEXT; + diff --git a/tools/quake2/extra/texpaint/texpaint.mak b/tools/quake2/extra/texpaint/texpaint.mak new file mode 100644 index 00000000..1a836604 --- /dev/null +++ b/tools/quake2/extra/texpaint/texpaint.mak @@ -0,0 +1,468 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=texpaint - Win32 Debug +!MESSAGE No configuration specified. Defaulting to texpaint - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "texpaint - Win32 Release" && "$(CFG)" !=\ + "texpaint - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "texpaint.mak" CFG="texpaint - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "texpaint - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "texpaint - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "texpaint - Win32 Debug" +MTL=mktyplib.exe +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "texpaint - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\texpaint.exe" + +CLEAN : + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\l3dslib.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\texmake.res" + -@erase "$(INTDIR)\texpaint.obj" + -@erase "$(INTDIR)\trilib.obj" + -@erase "$(INTDIR)\win_cam.obj" + -@erase "$(INTDIR)\win_main.obj" + -@erase "$(INTDIR)\win_pal.obj" + -@erase "$(INTDIR)\win_skin.obj" + -@erase "$(OUTDIR)\texpaint.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /ML /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\ + "_WINDOWS" /Fp"$(INTDIR)/texpaint.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/texmake.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/texpaint.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no\ + /pdb:"$(OUTDIR)/texpaint.pdb" /machine:I386 /out:"$(OUTDIR)/texpaint.exe" +LINK32_OBJS= \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\l3dslib.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\texmake.res" \ + "$(INTDIR)\texpaint.obj" \ + "$(INTDIR)\trilib.obj" \ + "$(INTDIR)\win_cam.obj" \ + "$(INTDIR)\win_main.obj" \ + "$(INTDIR)\win_pal.obj" \ + "$(INTDIR)\win_skin.obj" + +"$(OUTDIR)\texpaint.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "texpaint - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "texpaint" +# PROP BASE Intermediate_Dir "texpaint" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\texpaint.exe" + +CLEAN : + -@erase "$(INTDIR)\cmdlib.obj" + -@erase "$(INTDIR)\l3dslib.obj" + -@erase "$(INTDIR)\lbmlib.obj" + -@erase "$(INTDIR)\mathlib.obj" + -@erase "$(INTDIR)\scriplib.obj" + -@erase "$(INTDIR)\texmake.res" + -@erase "$(INTDIR)\texpaint.obj" + -@erase "$(INTDIR)\trilib.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(INTDIR)\win_cam.obj" + -@erase "$(INTDIR)\win_main.obj" + -@erase "$(INTDIR)\win_pal.obj" + -@erase "$(INTDIR)\win_skin.obj" + -@erase "$(OUTDIR)\texpaint.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN_ERROR" /YX /c +CPP_PROJ=/nologo /MLd /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /D "WIN_ERROR" /Fp"$(INTDIR)/texpaint.pch" /YX /Fo"$(INTDIR)/"\ + /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/texmake.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/texpaint.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /debug\ + /machine:I386 /out:"$(OUTDIR)/texpaint.exe" +LINK32_OBJS= \ + "$(INTDIR)\cmdlib.obj" \ + "$(INTDIR)\l3dslib.obj" \ + "$(INTDIR)\lbmlib.obj" \ + "$(INTDIR)\mathlib.obj" \ + "$(INTDIR)\scriplib.obj" \ + "$(INTDIR)\texmake.res" \ + "$(INTDIR)\texpaint.obj" \ + "$(INTDIR)\trilib.obj" \ + "$(INTDIR)\win_cam.obj" \ + "$(INTDIR)\win_main.obj" \ + "$(INTDIR)\win_pal.obj" \ + "$(INTDIR)\win_skin.obj" + +"$(OUTDIR)\texpaint.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "texpaint - Win32 Release" +# Name "texpaint - Win32 Debug" + +!IF "$(CFG)" == "texpaint - Win32 Release" + +!ELSEIF "$(CFG)" == "texpaint - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\texpaint.c +DEP_CPP_TEXPA=\ + "..\common\cmdlib.h"\ + "..\common\l3dslib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\trilib.h"\ + ".\texpaint.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\texpaint.obj" : $(SOURCE) $(DEP_CPP_TEXPA) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\mathlib.c +DEP_CPP_MATHL=\ + "..\..\..\quake\utils2\common\cmdlib.h"\ + "..\..\..\quake\utils2\common\mathlib.h"\ + + +"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\l3dslib.c +DEP_CPP_L3DSL=\ + "..\..\..\quake\utils2\common\cmdlib.h"\ + "..\..\..\quake\utils2\common\l3dslib.h"\ + "..\..\..\quake\utils2\common\mathlib.h"\ + "..\..\..\quake\utils2\common\trilib.h"\ + + +"$(INTDIR)\l3dslib.obj" : $(SOURCE) $(DEP_CPP_L3DSL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\lbmlib.c +DEP_CPP_LBMLI=\ + "..\..\..\quake\utils2\common\cmdlib.h"\ + "..\..\..\quake\utils2\common\lbmlib.h"\ + + +"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\scriplib.c +DEP_CPP_SCRIP=\ + "..\..\..\quake\utils2\common\cmdlib.h"\ + "..\..\..\quake\utils2\common\scriplib.h"\ + + +"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\trilib.c +DEP_CPP_TRILI=\ + "..\..\..\quake\utils2\common\cmdlib.h"\ + "..\..\..\quake\utils2\common\mathlib.h"\ + "..\..\..\quake\utils2\common\trilib.h"\ + + +"$(INTDIR)\trilib.obj" : $(SOURCE) $(DEP_CPP_TRILI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_skin.c +DEP_CPP_WIN_S=\ + "..\common\cmdlib.h"\ + "..\common\l3dslib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\trilib.h"\ + ".\texpaint.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_skin.obj" : $(SOURCE) $(DEP_CPP_WIN_S) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_main.c +DEP_CPP_WIN_M=\ + "..\common\cmdlib.h"\ + "..\common\l3dslib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\trilib.h"\ + ".\texpaint.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_main.obj" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_pal.c +DEP_CPP_WIN_P=\ + "..\common\cmdlib.h"\ + "..\common\l3dslib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\trilib.h"\ + ".\texpaint.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_pal.obj" : $(SOURCE) $(DEP_CPP_WIN_P) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\win_cam.c +DEP_CPP_WIN_C=\ + "..\common\cmdlib.h"\ + "..\common\l3dslib.h"\ + "..\common\lbmlib.h"\ + "..\common\mathlib.h"\ + "..\common\trilib.h"\ + ".\texpaint.h"\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLAUX.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + + +"$(INTDIR)\win_cam.obj" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\texmake.rc + +"$(INTDIR)\texmake.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\texpaint.h + +!IF "$(CFG)" == "texpaint - Win32 Release" + +!ELSEIF "$(CFG)" == "texpaint - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\lbmlib.h + +!IF "$(CFG)" == "texpaint - Win32 Release" + +!ELSEIF "$(CFG)" == "texpaint - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\cmdlib.h + +!IF "$(CFG)" == "texpaint - Win32 Release" + +!ELSEIF "$(CFG)" == "texpaint - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\quake\utils2\common\cmdlib.c +DEP_CPP_CMDLI=\ + "..\..\..\quake\utils2\common\cmdlib.h"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\types.h"\ + + +"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/tools/quake2/extra/texpaint/win_cam.c b/tools/quake2/extra/texpaint/win_cam.c new file mode 100644 index 00000000..5e1986d7 --- /dev/null +++ b/tools/quake2/extra/texpaint/win_cam.c @@ -0,0 +1,414 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "texpaint.h" + +#define CAMERA_WINDOW_CLASS "TPCamera" + +HDC camdc; +HGLRC baseRC; + +float pitch, yaw, roll; +qboolean model_lines = false; + +float cam_x, cam_y=-64, cam_z=32; + +int cam_width, cam_height; + +BINDTEXFUNCPTR BindTextureEXT; + +void InitIndexTexture (void) +{ + int i; + + BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + for (i=0 ; i= width2*height2) + return; + + if (index == cam_last_index) + return; // in same pixel + cam_last_index = index; + if (shift) + { + Pal_SetIndex (pic[index]); + return; + } + + SetSkin (index, selected_rgb); + UpdateWindow (camerawindow); +} + + +void Cam_DrawSetup (void) +{ + glViewport (0,0,cam_width, cam_height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + gluPerspective (90, (float)cam_width/cam_height, 2, 1024); + gluLookAt (cam_x, cam_y, cam_z, cam_x, cam_y+1, cam_z, 0, 0, 1); + + glRotated (-roll*0.3, 0, 1, 0); + glRotated (-pitch*0.3, 1, 0, 0); + glRotated (yaw*0.3, 0, 0, 1); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glEnable (GL_DEPTH_TEST); + glEnable (GL_CULL_FACE); + glEnable (GL_TEXTURE_2D); + glCullFace (GL_FRONT); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +void Cam_Draw (void) +{ + if (!cam_width || !cam_height) + return; + + glClearColor (0.3,0.3,0.3,1); + Cam_DrawSetup (); + + BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN); + + DrawModel (); + + if (model_lines) + { + glDisable (GL_TEXTURE_2D); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glDepthFunc (GL_LEQUAL); + glDepthRange (0, 0.999); // nudge depth to avoid dropouts + DrawModel (); + glDepthRange (0, 1); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glEnable (GL_TEXTURE_2D); + } + + SwapBuffers(camdc); + + // now fill the back buffer with the index texture + glClearColor (0,0,0,0); + glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX); + DrawModel (); + + BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN); +} + + + +/* +============ +CameraWndProc +============ +*/ +LONG WINAPI WCam_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LONG lRet = 1; + int fwKeys, xPos, yPos; + RECT rect; + static int oldx, oldy; + POINT pt; + + GetClientRect(hWnd, &rect); + cam_width = rect.right-rect.left; + cam_height = rect.bottom-rect.top; + + switch (uMsg) + { + case WM_CREATE: + camdc = GetDC(hWnd); + bSetupPixelFormat(camdc); + + baseRC = wglCreateContext( camdc ); + if (!baseRC) + Sys_Error ("wglCreateContext failed"); + if (!wglMakeCurrent( camdc, baseRC )) + Sys_Error ("wglMakeCurrent failed"); + BindTextureEXT = (void *)wglGetProcAddress((LPCSTR) "glBindTextureEXT"); + if (!BindTextureEXT) + Sys_Error ("GetProcAddress for BindTextureEXT failed"); + + break; + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hWnd, &ps); + if (!wglMakeCurrent( camdc, baseRC )) + Sys_Error ("wglMakeCurrent failed"); + Cam_Draw (); + EndPaint(hWnd, &ps); + } + break; + + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + if (GetTopWindow(mainwindow) != hWnd) + BringWindowToTop(hWnd); + + SetFocus (camerawindow); + SetCapture (camerawindow); + GetCursorPos (&pt); + xPos = pt.x; + yPos = pt.y; + oldx = xPos; + oldy = yPos; + break; + + case WM_LBUTTONDOWN: + cam_last_index = -1; +draw: + if (GetTopWindow(mainwindow) != hWnd) + BringWindowToTop(hWnd); + + SetFocus (camerawindow); + SetCapture (camerawindow); + fwKeys = wParam; // key flags + xPos = (short)LOWORD(lParam); // horizontal position of cursor + yPos = (short)HIWORD(lParam); // vertical position of cursor + yPos = (int)rect.bottom - 1 - yPos; + if (!wglMakeCurrent( camdc, baseRC )) + Sys_Error ("wglMakeCurrent failed"); + + Cam_Click (xPos, yPos, !!(wParam&(MK_SHIFT|MK_CONTROL)) ); + +// Cam_MouseDown (xPos, yPos, fwKeys); + break; + + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONUP: + if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); + break; + + case WM_MOUSEMOVE: + { + int dx, dy; + + if (wParam & MK_LBUTTON) + goto draw; + + GetCursorPos (&pt); + xPos = pt.x; + yPos = pt.y; + if (!(wParam & (MK_RBUTTON|MK_MBUTTON))) + { + oldx = xPos; + oldy = yPos; + break; + } + dx = xPos-oldx; + dy = oldy-yPos; + if (!dx && !dy) + break; + SetCursorPos (oldx, oldy); + + if (wParam == (MK_RBUTTON|MK_CONTROL) ) + { + if (abs(dx) > abs(dy)) + cam_y -= 0.1*dx; + else + cam_y -= 0.1*dy; + InvalidateRect (camerawindow, NULL, false); + } + if (wParam == MK_RBUTTON) + { + cam_x -= 0.1*dx; + cam_z -= 0.1*dy; + InvalidateRect (camerawindow, NULL, false); + } + if (wParam == (MK_MBUTTON|MK_CONTROL) ) + { + if (abs(dx) > abs(dy)) + roll -= dx; + else + roll -= dy; + InvalidateRect (camerawindow, NULL, false); + } + if (wParam == MK_MBUTTON) + { + yaw += dx; + pitch += dy; + InvalidateRect (camerawindow, NULL, false); + } + } + break; + + + + case WM_SIZE: +// camera.width = rect.right; +// camera.height = rect.bottom; + InvalidateRect(camerawindow, NULL, false); + break; + case WM_NCCALCSIZE:// don't let windows copy pixels + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + case WM_CLOSE: + /* call destroy window to cleanup and go away */ + DestroyWindow (hWnd); + break; + + case WM_DESTROY: + { + HGLRC hRC; + HDC hDC; + + /* release and free the device context and rendering context */ + hRC = wglGetCurrentContext(); + hDC = wglGetCurrentDC(); + + wglMakeCurrent(NULL, NULL); + + if (hRC) + wglDeleteContext(hRC); + if (hDC) + ReleaseDC(hWnd, hDC); + } + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + + +/* +============== +WCam_Register +============== +*/ +void WCam_Register (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WCam_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = CAMERA_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Sys_Error ("WCam_Register: failed"); +} + + +void WCam_Create (HINSTANCE hInstance) +{ + WCam_Register (hInstance); + + camerawindow = CreateWindow (CAMERA_WINDOW_CLASS , + "Camera View", + QE3_STYLE, + 0, + 0, + (int)(screen_width*0.5), + (int)(screen_height-20), // size + + mainwindow, // parent window + 0, // no menu + hInstance, + 0); + if (!camerawindow) + Sys_Error ("Couldn't create camerawindow"); + + RestoreWindowState(camerawindow, "camerawindow"); + ShowWindow (camerawindow, SW_SHOWDEFAULT); +} diff --git a/tools/quake2/extra/texpaint/win_main.c b/tools/quake2/extra/texpaint/win_main.c new file mode 100644 index 00000000..d377d7ba --- /dev/null +++ b/tools/quake2/extra/texpaint/win_main.c @@ -0,0 +1,496 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "texpaint.h" + +HINSTANCE main_instance; + +int screen_width, screen_height; + +HWND mainwindow; +HWND camerawindow; +HWND palettewindow; +HWND skinwindow; + +/* +================= +Sys_Error + +For abnormal program terminations +================= +*/ +void Sys_Error (char *error, ...) +{ + va_list argptr; + char text[1024]; + char text2[1024]; + int err; + + err = GetLastError (); + + va_start (argptr,error); + vsprintf (text, error,argptr); + va_end (argptr); + + sprintf (text2, "%s\nGetLastError() = %i", text, err); + MessageBox(mainwindow, text2, "Error", 0 /* MB_OK */ ); + + exit (1); +} + + +/* +====================================================================== + +FILE DIALOGS + +====================================================================== +*/ + +qboolean modified; +qboolean modified_past_autosave; + +qboolean ConfirmModified (void) +{ + if (!modified) + return true; + + if (MessageBox (mainwindow, "This will lose changes to the skin" + , "warning", MB_OKCANCEL) == IDCANCEL) + return false; + return true; +} + +OPENFILENAME ofn; /* common dialog box structure */ +char szDirName[MAX_PATH]; /* directory string */ +char szFile[260]; /* filename string */ +char szFileTitle[260]; /* file title string */ +char szSkinFilter[260] = /* filter string */ + "Skin texture (*.lbm *.pcx)\0*.lbm;*.pcx\0\0"; +char szFrameFilter[260] = /* filter string */ + "Model frame (*.tri)\0*.tri\0\0"; +char chReplace; /* string separator for szFilter */ +int i, cbString; /* integer count variables */ +HANDLE hf; /* file handle */ + +void OpenSkinDialog (void) +{ +// strcpy (szDirName, ValueForKey (project_entity, "basepath") ); +// strcat (szDirName, "\\maps"); + + /* Place the terminating null character in the szFile. */ + + szFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = mainwindow; + ofn.lpstrFilter = szSkinFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | + OFN_FILEMUSTEXIST; + + /* Display the Open dialog box. */ + + if (!GetOpenFileName(&ofn)) + return; // canceled + + Skin_LoadFile (ofn.lpstrFile); +} + +void OpenFrameDialog (void) +{ +// strcpy (szDirName, ValueForKey (project_entity, "basepath") ); +// strcat (szDirName, "\\maps"); + + /* Place the terminating null character in the szFile. */ + + szFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = mainwindow; + ofn.lpstrFilter = szFrameFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | + OFN_FILEMUSTEXIST; + + /* Display the Open dialog box. */ + + if (!GetOpenFileName(&ofn)) + return; // canceled + + LoadTriFile (ofn.lpstrFile); +} + +void SaveSkinDialog (void) +{ +// strcpy (szDirName, ValueForKey (project_entity, "basepath") ); +// strcat (szDirName, "\\maps"); + + /* Place the terminating null character in the szFile. */ + + szFile[0] = '\0'; + + /* Set the members of the OPENFILENAME structure. */ + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = mainwindow; + ofn.lpstrFilter = szSkinFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | + OFN_FILEMUSTEXIST; + + /* Display the Open dialog box. */ + + if (!GetSaveFileName(&ofn)) + return; // canceled + + DefaultExtension (ofn.lpstrFile, ".lbm"); + Skin_SaveFile (ofn.lpstrFile); + strcpy (skin_filename, ofn.lpstrFile); +} + +//========================================================================== + +BOOL bSetupPixelFormat(HDC hDC) +{ + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 32, // 32-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + int pixelformat = 0; + PIXELFORMATDESCRIPTOR newp; + + if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ) + { + printf("%d",GetLastError()); + Error ("ChoosePixelFormat failed"); + } + if (!SetPixelFormat(hDC, pixelformat, &pfd)) + Error ("SetPixelFormat failed"); + + return TRUE; +} + + +/* +============================================================================== + + MENU + +============================================================================== +*/ + + +/* handle all WM_COMMAND messages here */ +LONG WINAPI CommandHandler ( + HWND hWnd, + WPARAM wParam, + LPARAM lParam) +{ + unsigned short cmd; + + cmd = LOWORD(wParam); + + switch (cmd) + { + // + // file menu + // + case ID_FILE_RESAMPLESKIN: + ResampleSkin (); + break; + + case ID_FILE_NEWSKIN: + NewSkin (); + break; + + case ID_FILE_OPENFRAME: + OpenFrameDialog (); + break; + + case ID_FILE_OPENSKIN: + if (!ConfirmModified()) + break; + OpenSkinDialog (); + break; + + case ID_FILE_RELOADSKIN: + if (!ConfirmModified()) + break; + Skin_LoadFile (skin_filename); + break; + + case ID_FILE_SAVESKIN: + Skin_SaveFile (skin_filename); + break; + + case ID_FILE_SAVESKINAS: + SaveSkinDialog (); + break; + case ID_FILE_EXIT: + if (!ConfirmModified()) + break; + PostQuitMessage (0); + break; + + // + // edit menu + // + case ID_EDIT_UNDO: + Undo(); + break; + case ID_EDIT_REDO: + Redo(); + break; + + // + // view menu + // + case ID_VIEW_MODELLINES: + model_lines ^= 1; + CheckMenuItem ( GetSubMenu (GetMenu(mainwindow), MENU_VIEW) + , ID_VIEW_MODELLINES + , MF_BYCOMMAND | (model_lines ? MF_CHECKED : MF_UNCHECKED) ); + InvalidateRect (camerawindow, NULL, false); + break; + case ID_VIEW_TEXTURELINES: + skin_lines ^= 1; + CheckMenuItem ( GetSubMenu (GetMenu(mainwindow), MENU_VIEW) + , ID_VIEW_TEXTURELINES + , MF_BYCOMMAND | (skin_lines ? MF_CHECKED : MF_UNCHECKED) ); + InvalidateRect (skinwindow, NULL, false); + break; + default: + return FALSE; + } + + return TRUE; +} + +/* +============ +WMAIN_WndProc +============ +*/ +LONG WINAPI WMAIN_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LONG lRet = 1; + RECT rect; + HDC maindc; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_CREATE: + maindc = GetDC(hWnd); + bSetupPixelFormat(maindc); + break; + case WM_COMMAND: + lRet = CommandHandler (hWnd, wParam, lParam); + break; + + case WM_CLOSE: + if (!ConfirmModified()) + break; + PostQuitMessage (0); + break; + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + + + + +/* +============== +Main_Create +============== +*/ +void Main_Create (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)WMAIN_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU2); + wc.lpszClassName = "TEXPAINT_MAIN"; + + if (!RegisterClass (&wc) ) + Error ("WCam_Register: failed"); + + + mainwindow = CreateWindow ("TEXPAINT_MAIN" , + "Texpaint", + WS_OVERLAPPEDWINDOW | + WS_CLIPSIBLINGS | + WS_CLIPCHILDREN, + 0,0,screen_width,screen_height, // size + 0, + NULL, // no menu + hInstance, + NULL); + if (!mainwindow) + Error ("Couldn't create main window"); + +// GetWindowInfo("mainwindow", &SavedInfo, NULL); + ShowWindow (mainwindow, SW_SHOWDEFAULT); +} + + + + +BOOL SaveWindowInfo(const char *pszName, void *pvBuf, long lSize) +{ + LONG lres; + DWORD dwDisp; + HKEY hKeyId; + + lres = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\id\\Texpaint", 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyId, &dwDisp); + + if (lres != ERROR_SUCCESS) + return FALSE; + + lres = RegSetValueEx(hKeyId, pszName, 0, REG_BINARY, pvBuf, lSize); + + RegCloseKey(hKeyId); + + if (lres != ERROR_SUCCESS) + return FALSE; + + return TRUE; +} + + +BOOL GetWindowInfo(const char *pszName, void *pvBuf, long *plSize) +{ + HKEY hKey; + long lres, lType, lSize; + + if (plSize == NULL) + plSize = &lSize; + + lres = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\id\\Texpaint", 0, KEY_READ, &hKey); + + if (lres != ERROR_SUCCESS) + return FALSE; + + lres = RegQueryValueEx(hKey, pszName, NULL, &lType, pvBuf, plSize); + + RegCloseKey(hKey); + + if (lres != ERROR_SUCCESS) + return FALSE; + + return TRUE; + +} + +BOOL SaveWindowState(HWND hWnd, const char *pszName) +{ + RECT rc; + + GetWindowRect(hWnd, &rc); + MapWindowPoints(NULL, mainwindow, (POINT *)&rc, 2); + return SaveWindowInfo(pszName, &rc, sizeof(rc)); +} + + +BOOL RestoreWindowState(HWND hWnd, const char *pszName) +{ + RECT rc; + LONG lSize = sizeof(rc); + + if (GetWindowInfo(pszName, &rc, &lSize)) + { + if (rc.left < 0) + rc.left = 0; + if (rc.top < 0) + rc.top = 0; + if (rc.right < rc.left + 16) + rc.right = rc.left + 16; + if (rc.bottom < rc.top + 16) + rc.bottom = rc.top + 16; + + MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, + rc.bottom - rc.top, FALSE); + return TRUE; + } + + return FALSE; +} + diff --git a/tools/quake2/extra/texpaint/win_pal.c b/tools/quake2/extra/texpaint/win_pal.c new file mode 100644 index 00000000..09ebe51f --- /dev/null +++ b/tools/quake2/extra/texpaint/win_pal.c @@ -0,0 +1,257 @@ +/* +=========================================================================== +Copyright (C) 1997-2006 Id Software, Inc. + +This file is part of Quake 2 Tools source code. + +Quake 2 Tools source code 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. + +Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "texpaint.h" + +#define PALETTE_WINDOW_CLASS "TPPalette" + +HDC paldc; +int pal_width, pal_height; +int blocks_x, blocks_y; + +int selected_index; +unsigned selected_rgb; + +byte palette[768]; + +float SnapAspect (float aspect) +{ + if (aspect > 128) + return 256; + if (aspect > 32) + return 128; + if (aspect > 8) + return 64; + if (aspect > 2) + return 32; + return 16; +} + +void Pal_SetIndex (int index) +{ + selected_index = index; + selected_rgb = palette[index*3] + (palette[index*3+1]<<8) + (palette[index*3+2]<<16); + InvalidateRect (palettewindow, NULL, false); +} + +void Pal_Draw (void) +{ + int x, y; + float aspect; + float xs, ys; + int c; + + if (pal_width < 1 || pal_height < 1) + return; + + // + // determine the block arrangement + // + if (pal_width > pal_height) + { + aspect = SnapAspect (pal_width / pal_height); + blocks_x = aspect; + blocks_y = 256/blocks_x; + } + else + { + aspect = SnapAspect (pal_height / pal_width); + blocks_y = aspect; + blocks_x = 256/blocks_y; + } + + // + // draw it + // + glViewport (0,0,pal_width, pal_height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + glOrtho (0,1,0,1,-100,100); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glClear (GL_COLOR_BUFFER_BIT); + glDisable (GL_DEPTH_TEST); + glDisable (GL_CULL_FACE); + glDisable (GL_TEXTURE_2D); + + xs = 1.0/blocks_x; + ys = 1.0/blocks_y; + + for (x=0 ; xoffset = index; + m->oldvalue = pic[index]; + + modify_index = (++undo_index)&(MAX_MODIFY-1); + + // modify it + rgb[index] = selected_rgb; + pic[index] = selected_index; + UpdateTexture (index); + InvalidateRect (skinwindow, NULL, false); + InvalidateRect (camerawindow, NULL, false); +} + +void Undo (void) +{ + modify_t *m; + int temp; + + if (!undo_index) + return; + + if (!--undo_index) + { // back to unmodified state + modified = false; + SetWindowText (skinwindow, skin_filename); + } + m = &modify[undo_index]; + + // modify it + temp = pic[m->offset]; + pic[m->offset] = m->oldvalue; + rgb[m->offset] = palette[m->oldvalue*3] + + (palette[m->oldvalue*3+1]<<8) + (palette[m->oldvalue*3+2]<<16); + m->oldvalue = temp; + UpdateTexture (m->offset); + InvalidateRect (skinwindow, NULL, false); + InvalidateRect (camerawindow, NULL, false); + +} + +void Redo (void) +{ + modify_t *m; + int temp; + + if (undo_index == modify_index) + return; + + m = &modify[undo_index]; + + // modify it + temp = pic[m->offset]; + pic[m->offset] = m->oldvalue; + rgb[m->offset] = palette[m->oldvalue*3] + + (palette[m->oldvalue*3+1]<<8) + (palette[m->oldvalue*3+2]<<16); + m->oldvalue = temp; + UpdateTexture (m->offset); + InvalidateRect (skinwindow, NULL, false); + InvalidateRect (camerawindow, NULL, false); + + if (!undo_index++) + { // modified again + char text[1024]; + + modified = true; + sprintf (text, "%s *", skin_filename); + SetWindowText (skinwindow, text); + } +} + +//=================================================================== + +/* +============= +Skin_SaveFile + +Load a skin texture and the base.tri from the same directory +============= +*/ +void Skin_SaveFile (char *name) +{ + byte *data; + int i, j; + char backup[1024]; + + // back up the current file if it exists + sprintf (backup, "%s.bak", name); + remove (backup); + rename (name, backup); + + modified = false; + modified_past_autosave = false; + modify_index = undo_index = 0; + SetWindowText (skinwindow, skin_filename); + + data = malloc(skin_width*skin_height); + for (i=0 ; i 1024 || skin_height > 512) + Sys_Error ("Skin file is too large"); + + width2 = 1; + height2 = 1; + for (i=0 ; i<12 ; i++) + { + if (width2 < skin_width) + width2<<=1; + if (height2 < skin_height) + height2<<=1; + } + + // compatability shit for auto sizing of old skins + if (skin_width != 320 || skin_height != 200) + { + skinwidth = skin_width; + skinheight = skin_height; + } + else + { + skinwidth = 0; + skinheight = 0; + } +} + +/* +============= +Skin_LoadFile + +Load a skin texture and the base.tri from the same directory +============= +*/ +void Skin_LoadFile (char *name) +{ + int i, j, p; + byte *lbmpic; + byte *lbmpal; + char trifile[1024]; + int width, height; + + modified = false; + modified_past_autosave = false; + modify_index = undo_index = 0; + strcpy (skin_filename, name); + SetWindowText (skinwindow, skin_filename); + + // + // read the texture + // + Load256Image (skin_filename, &lbmpic, &lbmpal, &width, &height); + memcpy (palette, lbmpal, sizeof(palette)); + free (lbmpal); + + SetSizes (width, height); + + memset (pic, 0, sizeof(pic)); + for (i=0 ; i= width2*height2) + return; + + if (index == skin_last_index) + return; // in same pixel + skin_last_index = index; + + if (shift) + { + Pal_SetIndex (pic[index]); + return; + } + + SetSkin (index, selected_index); + UpdateWindow (skinwindow); +} + + +void DrawModelST (void) +{ + int i, j; + + glColor4f (1,1,1,1); + + glBegin (GL_TRIANGLES); + for (i=0 ; i abs(dy)) + skin_z += 0.25*dx; + else + skin_z += 0.25*dy; + InvalidateRect (skinwindow, NULL, false); + } + if (wParam == MK_RBUTTON) + { + skin_x -= 0.25*dx; + skin_y -= 0.25*dy; + InvalidateRect (skinwindow, NULL, false); + } + } + break; + + case WM_SIZE: + InvalidateRect(camerawindow, NULL, false); + break; + case WM_NCCALCSIZE:// don't let windows copy pixels + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + case WM_CLOSE: + DestroyWindow (hWnd); + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + + +/* +============== +WSkin_Create +============== +*/ +void WSkin_Create (HINSTANCE hInstance) +{ + WNDCLASS wc; + + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)Skin_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = SKIN_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Sys_Error ("RegisterClass failed"); + + skinwindow = CreateWindow (SKIN_WINDOW_CLASS , + "Skin View", + QE3_STYLE, + (int)(screen_width*0.5), + (int)(screen_height*0.2), + (int)(screen_width*0.5), + (int)(screen_height*0.8), // size + mainwindow, // parent window + 0, // no menu + hInstance, + 0); + if (!skinwindow) + Error ("Couldn't create skinwindow"); + +// RestoreWindowState(palettewindow, "palettewindow"); + ShowWindow (skinwindow, SW_SHOWDEFAULT); +} + + +/* +=================================================================== + + SKIN RESAMPLING + +=================================================================== +*/ + +HWND resamplewindow; +HDC resampledc; + +#define RESAMPLE_WINDOW_CLASS "TPResample" + +/* +============ +Resample_WndProc +============ +*/ +LONG WINAPI Resample_WndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_CREATE: + resampledc = GetDC(hWnd); + bSetupPixelFormat(resampledc); + break; + } + + return DefWindowProc (hWnd, uMsg, wParam, lParam); +} + +/* +============== +ResampleWindow +============== +*/ +void ResampleWindow (HINSTANCE hInstance) +{ + WNDCLASS wc; + static qboolean registered; + + if (!registered) + { + registered = true; + /* Register the camera class */ + memset (&wc, 0, sizeof(wc)); + + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)Resample_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = RESAMPLE_WINDOW_CLASS; + + if (!RegisterClass (&wc) ) + Sys_Error ("RegisterClass failed"); + } + + resamplewindow = CreateWindow (RESAMPLE_WINDOW_CLASS , + "ResampleWindow", + WS_OVERLAPPED, + 0, 0, width2+32, height2+32, // size + NULL, // parent window + 0, // no menu + hInstance, + 0); + if (!resamplewindow) + Error ("Couldn't create skinwindow"); + + ShowWindow (resamplewindow, SW_SHOWDEFAULT); +} + + +void OutlineTexture (byte *pic) +{ + int i, j; + int x, y; + int empty; + byte oldpic[1024*512]; + + memcpy (oldpic, pic, width2*height2); + + empty = oldpic[0]; + + for (i=0 ; i= height2) + continue; + if (j+x < 0 || j+x >= width2) + continue; + if (oldpic[(i+y)*width2 + j+x] != empty) + { + pic[i*width2+j] = oldpic[(i+y)*width2 + j+x]; + goto done; + } + } + } +done: ; + } + } +} + +void ResampleSkin (void) +{ + int i, j; + static float oldtmcoords[10000][3][2]; + static int newindex[1024*512]; + static byte oldpic[1024*512]; + + // open a window of the texture size + ResampleWindow (main_instance); + + // get new S/T from current frame + memcpy (oldtmcoords, tmcoords, numfaces*3*2*4); + CalcTmCoords (); + + // draw all the triangles with the index texture + if (!wglMakeCurrent( resampledc, baseRC )) + Sys_Error ("wglMakeCurrent failed"); + + glViewport (0,0,width2, height2); + glClearColor (0,0,0,0); + glClear (GL_COLOR_BUFFER_BIT); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + glOrtho (0, width2, 0, height2, -100, 100); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glColor4f (1,1,1,1); + glDisable (GL_DEPTH_TEST); + glDisable (GL_CULL_FACE); + BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX); +#if 0 + glDisable(GL_TEXTURE_2D); + glBegin (GL_LINE_LOOP); + glVertex3f (1,1,10); + glVertex3f (skin_width-1,0,10); + glVertex3f (skin_width-1,skin_height-1,10); + glVertex3f (1,skin_height-1,10); + glEnd (); + glEnable(GL_TEXTURE_2D); +#endif + glBegin (GL_TRIANGLES); + for (i=0 ; i Date: Sun, 8 Apr 2012 18:45:33 -0500 Subject: [PATCH 02/16] moved to the web repository. online at http://icculus.org/gtkradiant/documentation/windows_compile_guide/ --- windows_compile_guide/index.html | 226 ------------------- windows_compile_guide/vc-radiant-release.png | Bin 53964 -> 0 bytes 2 files changed, 226 deletions(-) delete mode 100644 windows_compile_guide/index.html delete mode 100644 windows_compile_guide/vc-radiant-release.png diff --git a/windows_compile_guide/index.html b/windows_compile_guide/index.html deleted file mode 100644 index f3676278..00000000 --- a/windows_compile_guide/index.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - Compiling GtkRadiant on Windows - - - -
- - Valid XHTML 1.0! - -
-
-

Compiling GtkRadiant on Windows

-
-

This guide explains how to compile GtkRadiant 1.6.x from source code on Windows operating systems. - The source code is obtained from - the GtkRadiant Git repository, which is open to the public (details follow). - These instructions are aimed at developers wanting to test changes to GtkRadiant source code. - The instructions below have been executed successfully on - Windows XP 32 bit (some late service pack) and on Windows 7 Professional 64 bit.

-

This guide is divided into the following main sections. -

- -
-
- -

Section 1: Installing Git

-

- First to install is the Git, Git is a powerful distributed Source Code Management tool and the versioning tool of choice for GtkRadiant development. -

-

- The hompepage for Git is git-scm.com, but we are more interested in - code.google.com/p/msysgit/ because this is the windows port of git. You should - download and install the newest "Full installer for official Git for Windows". -

-
-
- -

Section 2: Installing Python

-

We will now install the Python programming language, which is needed for SCons to work.

-

- The homepage for Python is www.python.org. You should download and install - a 32 bit version of Python, because scons is only avaiable in 32 bit builds. I would strongly recommend sticking to a version of Python - that is 2.x.x, not 3.x.x. This is because lots of legacy software that uses Python is known to work correctly - with 2.x.x, but might not necessarily work with 3.x.x. At the time of writing this tutorial, the preferred version of Python - was 2.7.1. For purposes of this tutorial, Python is installed to C:\Python27 . All of the default - options for installing Python should be fine. -

-
-
- -

Section 3: Installing SCons

-

We will now install SCons, which is a multi-platform substitute for traditional Make.

-

- The homepage for SCons is www.scons.org. You should download and install the - latest production release. During the install procedure you will be asked to confirm the location of your Python - installation. -

-
-
- -

Section 4: Installing SVN

-

- We're now going to install a command-line version of the SVN client that we can use from cmd. We don't need no - stinkin' GUI. Anyhow, command-line SVN is required to perform the SCons build target later on. - In fact, you don't need to touch TortoiseSVN or any other GUI-based SVN client for any part of this entire tutorial. - (I wouldn't touch a GUI-based SVN client with a 10 foot pole given the opportunity to use command-line SVN instead.) -

-

- The preferred download site for SVN client for Windows is CollabNet. - You should download and install CollabNet Subversion Command-Line Client, - not CollabNet Subversion Edge or something of any other nature. Unfortunately you'll have to create an account with CollabNet - to download this software, but everything is free. You can use all defaults when installing SVN. -

-

- The CollabNet version of SVN client for Windows should automatically modify your PATH , and you should be able to - execute the svn command in cmd after closing cmd and starting it again. If this is not the case for some strange - reason, you'll have to tweak your environment to ensure that you can execute the svn command from cmd. -

-
-
- -

Section 5: Installing Visual C++

-

- The GtkRadiant developers are currently using Microsoft Visual C++ 2008 to compile GtkRadiant. Even though Visual C++ 2010 is a newer - version, don't use it [unless you want to be on your own]. You can download Visual C++ 2008 Express Edition from - this Microsoft webpage. -

-

- When you install Visual C++ 2008 Express Edition, you can install the bare minimum application without any extras such as - Microsoft Silverlight Runtime or Microsoft SQL Server 2008 Express Edition. For the rest of the install options, the - defaults can be chosen. -

-
-
- -

Section 6: Obtaining Source Code, Game Paks, and Libs

-

We are now ready to get the source code for GtkRadiant.

-

Step A: Get Base Project

-

- Open an Git Bash shell. When you start the shell, you will be in what is called your "home directory". You can execute the - pwd command in Git Bash to find out which directory you are currently in. For example, when I start Git Bash, my - current directory is /c/Users/Christian . -

-

- In any case, we need to create ourselves a work area for purposes of downloading files and compiling software. I would recommend - creating a directory radiant-work in your home directory. So: -

-
-
$ mkdir radiant-work
-
-
-

Now, we're going to change to that directory and get the base GtkRadiant project:

-
-
$ cd radiant-work
-$ git clone git://github.com/TTimo/GtkRadiant.git
-
-
-

We created the extra radiant-work parent directory of GtkRadiant because the following step will - place many files into the project's parent directory, and we don't want to litter our home directory with these files.

-

Step B: Execute SCons Build Target

-

- Remember all the work we did earlier in order to install SCons? Well, thanks to all that work we did, - obtaining the remaining things we need for compiling is really really easy: -

-

- Open a cmd shell and execute: -

-
-
$ cd radiant-work\GtkRadiant
-$ C:\Python27\Scripts\scons.bat target=setup
-
-
-

This SCons build target performs several actions:

-
    -
  • Downloads "install paks" for several games such as Quake III Arena and Urban Terror.
  • -
  • Downloads library dependencies (such as GTK+) for building and running GtkRadiant.
  • -
  • Places library dependencies in proper locations.
  • -
  • Performs any other actions needed prior to compiling GtkRadiant.
  • -
-
-
- -

Section 7: Compiling GtkRadiant

-

We are now finally going to compile GtkRadiant using Microsoft Visual C++.

-

- Start Microsoft Visual C++. From the "File" menu, choose "Open" -> "Project/Solution...". - Navigate to your GtkRadiant directory (in my case C:\Users\Christian\radiant-work\GtkRadiant). - Choose the project file radiant.sln from this directory. -

-

- You now have the GtkRadiant project loaded in Visual C++. You can poke around if you like, e.g. open up some source code - files and edit them. -

-

- Before you build the project, you might want to select the "Release" target (as pictured below). -

- - - - - -
 vc-radiant-release.png
-

- To build GtkRadiant, choose "Build Solution" from the "Build" menu. The build will take - about 10 minutes [on a Pentium 4 with HTT], so this would be a good time to go get a cup of tea. -

-

If the build completes successfully, you will get a message similar to the following in the output - of Visual C++:

-
-
radiant - 0 error(s), 0 warning(s)
-========== Build: 38 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
-
-
-
-
- -

Section 8: Running GtkRadiant

-

All of the files needed to run GtkRadiant are going to be in the folder radiant-work\GtkRadiant\install [relative - to your home directory]. You can copy the entire install folder to some place such as your Desktop - and you can rename this folder to ZeroRadiant for example. - Then, you will use radiant.exe in that directory to launch the application. -

-

- There is one little bit of optional cleanup you can perform on your installation folder. You can remove all SVN-related - files since they are no longer needed and only take up disk space. Let's say that you renamed your installation folder - to ZeroRadiant (as the previous paragraph suggests), and let's say that you're in the cmd shell, and that your current - working directory is the directory of ZeroRadiant. Then, in your cmd shell, you can execute this command to - delete all SVN-related files (all .svn directories): -

-
-
$ for /r %R in (.svn) do if exist %R (rd /s /q "%R")
-
-
-

- That's it! Good luck and thanks for reading this enhanced tutorial! If you have comments or suggestions please email me at nlandys@gmail.com or the updater christian_ratzenhofer@yahoo.de. - More information about GtkRadiant is on icculus.org/gtkradiant. -

-
-
- - diff --git a/windows_compile_guide/vc-radiant-release.png b/windows_compile_guide/vc-radiant-release.png deleted file mode 100644 index 1b8b11c95c7c5b44f446f7be3f1849751af63a9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53964 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 TzQ~V!00000NkvXXu0mjf#yPTO From 85a66c95194d3c608040bc93bd7c241ec323c095 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sat, 14 Apr 2012 17:15:55 -0500 Subject: [PATCH 03/16] fix unzip code --- plugins/vfspk3/unzip.cpp | 5429 +++++++++++++++++----------------- tools/quake3/common/unzip.c | 5454 +++++++++++++++++------------------ 2 files changed, 5341 insertions(+), 5542 deletions(-) diff --git a/plugins/vfspk3/unzip.cpp b/plugins/vfspk3/unzip.cpp index 8d89a9ec..7390894a 100644 --- a/plugins/vfspk3/unzip.cpp +++ b/plugins/vfspk3/unzip.cpp @@ -1,10 +1,17 @@ +/* +WARNING: DO NOT UNCRUSTIFY +It will still compile after an uncrustify, but it will be *broken* +See https://github.com/TTimo/GtkRadiant/issues/33 +*/ + + /***************************************************************************** -* name: unzip.c -* -* desc: IO on .zip files using portions of zlib -* -* -*****************************************************************************/ + * name: unzip.c + * + * desc: IO on .zip files using portions of zlib + * + * + *****************************************************************************/ #include #include @@ -13,7 +20,7 @@ typedef unsigned char byte; -/* unzip.h -- IO for uncompress .zip files using zlib +/* unzip.h -- IO for uncompress .zip files using zlib Version 0.15 beta, Mar 19th, 1998, Copyright (C) 1998 Gilles Vollant @@ -30,65 +37,64 @@ typedef unsigned char byte; Condition of use and distribution are the same than zlib : - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. + 3. This notice may not be removed or altered from any source distribution. - */ -/* for more info about .ZIP format, see +*/ +/* for more info about .ZIP format, see ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip PkWare has also a specification at : ftp://ftp.pkware.com/probdesc.zip */ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.1.3, July 9th, 1998 + version 1.1.3, July 9th, 1998 - Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. + 3. This notice may not be removed or altered from any source distribution. - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). - */ + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-1998 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ - #ifndef _ZCONF_H #define _ZCONF_H @@ -112,26 +118,26 @@ typedef unsigned char byte; /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). + Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. - */ + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ -/* Type declarations */ + /* Type declarations */ #ifndef OF /* function prototypes */ -#define OF( args ) args +#define OF(args) args #endif -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ typedef Byte *voidp; #ifndef SEEK_SET @@ -144,26 +150,26 @@ typedef Byte *voidp; #define ZLIB_VERSION "1.1.3" -/* +/* The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio. + with an interface similar to that of stdio. The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. - */ + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ /* The application must update next_in and avail_in when avail_in has @@ -195,9 +201,9 @@ typedef Byte *voidp; the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). - */ +*/ -/* constants */ + /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ @@ -209,12 +215,12 @@ typedef Byte *voidp; #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 -#define Z_ERRNO ( -1 ) -#define Z_STREAM_ERROR ( -2 ) -#define Z_DATA_ERROR ( -3 ) -#define Z_MEM_ERROR ( -4 ) -#define Z_BUF_ERROR ( -5 ) -#define Z_VERSION_ERROR ( -6 ) +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ @@ -222,7 +228,7 @@ typedef Byte *voidp; #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION ( -1 ) +#define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 @@ -243,17 +249,17 @@ typedef Byte *voidp; #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ -/* basic functions */ + /* basic functions */ -const char * zlibVersion OF( (void) ); +const char * zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ -/* - int deflateInit OF((z_streamp strm, int level)); +/* +int deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. @@ -272,88 +278,88 @@ const char * zlibVersion OF( (void) ); with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). - */ +*/ -int deflate OF( ( z_streamp strm, int flush ) ); +int deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. The detailed semantics are as follows. deflate performs one or both of the - following actions: + following actions: - - Compress more input starting at next_in and update next_in and avail_in + - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - the compression. + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read - so (that is, total_in bytes). + so (that is, total_in bytes). deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). - */ + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ -int deflateEnd OF( (z_streamp strm) ); +int deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any @@ -364,11 +370,11 @@ int deflateEnd OF( (z_streamp strm) ); prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). - */ +*/ -/* - int inflateInit OF((z_streamp strm)); +/* +int inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by @@ -385,79 +391,79 @@ int deflateEnd OF( (z_streamp strm) ); message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) - */ +*/ -int inflate OF( ( z_streamp strm, int flush ) ); +int inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may some - introduce some output latency (reading input without producing any output) - except when forced to flush. + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. - The detailed semantics are as follows. inflate performs one or both of the - following actions: + The detailed semantics are as follows. inflate performs one or both of the + following actions: - - Decompress more input starting at next_in and update next_in and avail_in + - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much - output as possible to the output buffer. The flushing behavior of inflate is - not specified for values of the flush parameter other than Z_SYNC_FLUSH - and Z_FINISH, but the current implementation actually flushes as much output - as possible anyway. + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. If a preset dictionary is needed at this point (see inflateSetDictionary - below), inflate sets strm-adler to the adler32 checksum of the - dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise - it sets strm->adler to the adler32 checksum of all output produced - so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or - an error code as described below. At the end of the stream, inflate() - checks that its computed adler32 checksum is equal to that saved by the - compressor and returns Z_STREAM_END only if the checksum is correct. + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect - adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent - (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if no progress is possible or if there was not - enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR - case, the application may then call inflateSync to look for a good - compression block. - */ + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ -int inflateEnd OF( (z_streamp strm) ); +int inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any @@ -466,16 +472,16 @@ int inflateEnd OF( (z_streamp strm) ); inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). - */ +*/ -/* Advanced functions */ + /* Advanced functions */ /* The following functions are needed only in some special applications. - */ +*/ -/* - int deflateInit2 OF((z_streamp strm, +/* +int deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, @@ -516,11 +522,11 @@ int inflateEnd OF( (z_streamp strm) ); memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). - */ - -int deflateSetDictionary OF( ( z_streamp strm, - const Byte * dictionary, - uInt dictLength ) ); +*/ + +int deflateSetDictionary OF((z_streamp strm, + const Byte *dictionary, + uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called @@ -552,10 +558,10 @@ int deflateSetDictionary OF( ( z_streamp strm, inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). - */ +*/ -int deflateCopy OF( ( z_streamp dest, - z_streamp source ) ); +int deflateCopy OF((z_streamp dest, + z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. @@ -570,9 +576,9 @@ int deflateCopy OF( ( z_streamp dest, enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. - */ +*/ -int deflateReset OF( (z_streamp strm) ); +int deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. @@ -581,11 +587,11 @@ int deflateReset OF( (z_streamp strm) ); deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). - */ +*/ -int deflateParams OF( ( z_streamp strm, - int level, - int strategy ) ); +int deflateParams OF((z_streamp strm, + int level, + int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be @@ -602,10 +608,10 @@ int deflateParams OF( ( z_streamp strm, deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. - */ +*/ -/* - int inflateInit2 OF((z_streamp strm, +/* +int inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The @@ -625,11 +631,11 @@ int deflateParams OF( ( z_streamp strm, does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) - */ +*/ -int inflateSetDictionary OF( ( z_streamp strm, - const Byte * dictionary, - uInt dictLength ) ); +int inflateSetDictionary OF((z_streamp strm, + const Byte *dictionary, + uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate @@ -644,24 +650,24 @@ int inflateSetDictionary OF( ( z_streamp strm, expected one (incorrect Adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). - */ +*/ -int inflateSync OF( (z_streamp strm) ); -/* +int inflateSync OF((z_streamp strm)); +/* Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. - */ + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ -int inflateReset OF( (z_streamp strm) ); +int inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. @@ -669,10 +675,10 @@ int inflateReset OF( (z_streamp strm) ); inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). - */ +*/ -/* utility functions */ + /* utility functions */ /* The following utility functions are implemented on top of the @@ -680,10 +686,10 @@ int inflateReset OF( (z_streamp strm) ); default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can easily be modified if you need special options. - */ +*/ -int compress OF( ( Byte * dest, uLong * destLen, - const Byte * source, uLong sourceLen ) ); +int compress OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total @@ -695,11 +701,11 @@ int compress OF( ( Byte * dest, uLong * destLen, compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. - */ +*/ -int compress2 OF( ( Byte * dest, uLong * destLen, - const Byte * source, uLong sourceLen, - int level ) ); +int compress2 OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen, + int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -710,10 +716,10 @@ int compress2 OF( ( Byte * dest, uLong * destLen, compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. - */ +*/ -int uncompress OF( ( Byte * dest, uLong * destLen, - const Byte * source, uLong sourceLen ) ); +int uncompress OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total @@ -728,12 +734,12 @@ int uncompress OF( ( Byte * dest, uLong * destLen, uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. - */ +*/ typedef voidp gzFile; -gzFile gzopen OF( ( const char *path, const char *mode ) ); +gzFile gzopen OF((const char *path, const char *mode)); /* Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level @@ -749,7 +755,7 @@ gzFile gzopen OF( ( const char *path, const char *mode ) ); can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ -gzFile gzdopen OF( ( int fd, const char *mode ) ); +gzFile gzdopen OF((int fd, const char *mode)); /* gzdopen() associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or @@ -760,17 +766,17 @@ gzFile gzdopen OF( ( int fd, const char *mode ) ); descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). gzdopen returns NULL if there was insufficient memory to allocate the (de)compression state. - */ +*/ -int gzsetparams OF( ( gzFile file, int level, int strategy ) ); +int gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. - */ +*/ -int gzread OF( ( gzFile file, voidp buf, unsigned len ) ); +int gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number @@ -778,50 +784,50 @@ int gzread OF( ( gzFile file, voidp buf, unsigned len ) ); gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error). */ -int gzwrite OF( ( gzFile file, - const voidp buf, unsigned len ) ); +int gzwrite OF((gzFile file, + const voidp buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes actually written (0 in case of error). - */ +*/ -int gzprintf OF( ( gzFile file, const char *format, ... ) ); +int gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). - */ +*/ -int gzputs OF( ( gzFile file, const char *s ) ); +int gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. - */ +*/ -char * gzgets OF( ( gzFile file, char *buf, int len ) ); +char * gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. - */ +*/ -int gzputc OF( ( gzFile file, int c ) ); +int gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. - */ +*/ -int gzgetc OF( (gzFile file) ); +int gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. - */ +*/ -int gzflush OF( ( gzFile file, int flush ) ); +int gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib @@ -829,11 +835,11 @@ int gzflush OF( ( gzFile file, int flush ) ); the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression. - */ +*/ -long gzseek OF( ( gzFile file, - long offset, int whence ) ); -/* +long gzseek OF((gzFile file, + long offset, int whence)); +/* Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); @@ -847,55 +853,55 @@ long gzseek OF( ( gzFile file, the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. - */ +*/ -int gzrewind OF( (gzFile file) ); +int gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) - */ +*/ -long gztell OF( (gzFile file) ); +long gztell OF((gzFile file)); /* Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) - */ +*/ -int gzeof OF( (gzFile file) ); +int gzeof OF((gzFile file)); /* Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. - */ +*/ -int gzclose OF( (gzFile file) ); +int gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below). - */ +*/ -const char * gzerror OF( ( gzFile file, int *errnum ) ); +const char * gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. - */ +*/ -/* checksum functions */ + /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. - */ +*/ -uLong adler32 OF( ( uLong adler, const Byte * buf, uInt len ) ); +uLong adler32 OF((uLong adler, const Byte *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and @@ -910,9 +916,9 @@ uLong adler32 OF( ( uLong adler, const Byte * buf, uInt len ) ); adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); - */ +*/ -uLong crc32 OF( ( uLong crc, const Byte * buf, uInt len ) ); +uLong crc32 OF((uLong crc, const Byte *buf, uInt len)); /* Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value @@ -926,66 +932,72 @@ uLong crc32 OF( ( uLong crc, const Byte * buf, uInt len ) ); crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); - */ +*/ // private stuff to not include cmdlib.h /* - ============================================================================ +============================================================================ - BYTE ORDER FUNCTIONS + BYTE ORDER FUNCTIONS - ============================================================================ - */ +============================================================================ +*/ #ifdef _SGI_SOURCE -#define __BIG_ENDIAN__ +#define __BIG_ENDIAN__ #endif #ifdef __BIG_ENDIAN__ -short __LittleShort( short l ){ - byte b1,b2; +short __LittleShort (short l) +{ + byte b1,b2; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; - return ( b1 << 8 ) + b2; + return (b1<<8) + b2; } -short __BigShort( short l ){ +short __BigShort (short l) +{ return l; } -int __LittleLong( int l ){ - byte b1,b2,b3,b4; +int __LittleLong (int l) +{ + byte b1,b2,b3,b4; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - b3 = ( l >> 16 ) & 255; - b4 = ( l >> 24 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; - return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } -int __BigLong( int l ){ +int __BigLong (int l) +{ return l; } -float __LittleFloat( float l ){ - union {byte b[4]; float f; } in, out; - +float __LittleFloat (float l) +{ + union {byte b[4]; float f;} in, out; + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } -float __BigFloat( float l ){ +float __BigFloat (float l) +{ return l; } @@ -993,48 +1005,54 @@ float __BigFloat( float l ){ #else -short __BigShort( short l ){ - byte b1,b2; +short __BigShort (short l) +{ + byte b1,b2; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; - return ( b1 << 8 ) + b2; + return (b1<<8) + b2; } -short __LittleShort( short l ){ +short __LittleShort (short l) +{ return l; } -int __BigLong( int l ){ - byte b1,b2,b3,b4; +int __BigLong (int l) +{ + byte b1,b2,b3,b4; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - b3 = ( l >> 16 ) & 255; - b4 = ( l >> 24 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; - return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } -int __LittleLong( int l ){ +int __LittleLong (int l) +{ return l; } -float __BigFloat( float l ){ - union {byte b[4]; float f; } in, out; - +float __BigFloat (float l) +{ + union {byte b[4]; float f;} in, out; + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } -float __LittleFloat( float l ){ +float __LittleFloat (float l) +{ return l; } @@ -1045,50 +1063,50 @@ float __LittleFloat( float l ){ -/* various hacks, don't look :) */ + /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ -int deflateInit_ OF( ( z_streamp strm, int level, - const char *version, int stream_size ) ); -int inflateInit_ OF( ( z_streamp strm, - const char *version, int stream_size ) ); -int deflateInit2_ OF( ( z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size ) ); -int inflateInit2_ OF( ( z_streamp strm, int windowBits, - const char *version, int stream_size ) ); -#define deflateInit( strm, level ) \ - deflateInit_( ( strm ), ( level ), ZLIB_VERSION, sizeof( z_stream ) ) -#define inflateInit( strm ) \ - inflateInit_( ( strm ), ZLIB_VERSION, sizeof( z_stream ) ) -#define deflateInit2( strm, level, method, windowBits, memLevel, strategy ) \ - deflateInit2_( ( strm ),( level ),( method ),( windowBits ),( memLevel ), \ - ( strategy ), ZLIB_VERSION, sizeof( z_stream ) ) -#define inflateInit2( strm, windowBits ) \ - inflateInit2_( ( strm ), ( windowBits ), ZLIB_VERSION, sizeof( z_stream ) ) +int deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +int inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +int deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +int inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -const char * zError OF( (int err) ); -int inflateSyncPoint OF( (z_streamp z) ); -const uLong * get_crc_table OF( (void) ); +const char * zError OF((int err)); +int inflateSyncPoint OF((z_streamp z)); +const uLong * get_crc_table OF((void)); -typedef unsigned char uch; +typedef unsigned char uch; typedef unsigned short ush; -typedef unsigned long ulg; +typedef unsigned long ulg; extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG( err ) z_errmsg[Z_NEED_DICT - ( err )] +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] -#define ERR_RETURN( strm,err ) \ - return ( strm->msg = (char*)ERR_MSG( err ), ( err ) ) +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ -/* common constants */ + /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS @@ -1113,84 +1131,84 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ -/* target dependencies */ + /* target dependencies */ -/* Common defaults */ + /* Common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN -# define F_OPEN( name, mode ) fopen( ( name ), ( mode ) ) +# define F_OPEN(name, mode) fopen((name), (mode)) #endif -/* functions */ + /* functions */ #ifdef HAVE_STRERROR -extern char *strerror OF( (int) ); -# define zstrerror( errnum ) strerror( errnum ) + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) #else -# define zstrerror( errnum ) "" +# define zstrerror(errnum) "" #endif #define zmemcpy memcpy #define zmemcmp memcmp -#define zmemzero( dest, len ) memset( dest, 0, len ) +#define zmemzero(dest, len) memset(dest, 0, len) /* Diagnostic functions */ #ifdef _ZIP_DEBUG_ -int z_verbose = 0; -# define Assert( cond,msg ) assert( cond ); -//{if(!(cond)) Sys_Error(msg);} -# define Trace( x ) {if ( z_verbose >= 0 ) {Sys_Error x ; }} -# define Tracev( x ) {if ( z_verbose > 0 ) {Sys_Error x ; }} -# define Tracevv( x ) {if ( z_verbose > 1 ) {Sys_Error x ; }} -# define Tracec( c,x ) {if ( z_verbose > 0 && ( c ) ) {Sys_Error x ; }} -# define Tracecv( c,x ) {if ( z_verbose > 1 && ( c ) ) {Sys_Error x ; }} + int z_verbose = 0; +# define Assert(cond,msg) assert(cond); + //{if(!(cond)) Sys_Error(msg);} +# define Trace(x) {if (z_verbose>=0) Sys_Error x ;} +# define Tracev(x) {if (z_verbose>0) Sys_Error x ;} +# define Tracevv(x) {if (z_verbose>1) Sys_Error x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) Sys_Error x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) Sys_Error x ;} #else -# define Assert( cond,msg ) -# define Trace( x ) -# define Tracev( x ) -# define Tracevv( x ) -# define Tracec( c,x ) -# define Tracecv( c,x ) +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) #endif -typedef uLong ( *check_func ) OF ( ( uLong check, const Byte * buf, uInt len ) ); -voidp zcalloc OF( ( voidp opaque, unsigned items, unsigned size ) ); -void zcfree OF( ( voidp opaque, voidp ptr ) ); +typedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len)); +voidp zcalloc OF((voidp opaque, unsigned items, unsigned size)); +void zcfree OF((voidp opaque, voidp ptr)); -#define ZALLOC( strm, items, size ) \ - ( *( ( strm )->zalloc ) )( ( strm )->opaque, ( items ), ( size ) ) -#define ZFREE( strm, addr ) ( *( ( strm )->zfree ) )( ( strm )->opaque, (voidp)( addr ) ) -#define TRY_FREE( s, p ) {if ( p ) {ZFREE( s, p ); }} +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} -#if !defined( unix ) && !defined( CASESENSITIVITYDEFAULT_YES ) && \ - !defined( CASESENSITIVITYDEFAULT_NO ) +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) #define CASESENSITIVITYDEFAULT_NO #endif #ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE ( 65536 ) +#define UNZ_BUFSIZE (65536) #endif #ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP ( 256 ) +#define UNZ_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC -# define ALLOC( size ) ( malloc( size ) ) +# define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE -# define TRYFREE( p ) {if ( p ) {free( p ); }} +# define TRYFREE(p) {if (p) free(p);} #endif -#define SIZECENTRALDIRITEM ( 0x2e ) -#define SIZEZIPLOCALHEADER ( 0x1e ) +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) @@ -1198,37 +1216,38 @@ void zcfree OF( ( voidp opaque, voidp ptr ) ); Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading. - */ +*/ /* - static int unzlocal_getByte(FILE *fin,int *pi) - { +static int unzlocal_getByte(FILE *fin,int *pi) +{ unsigned char c; - int err = fread(&c, 1, 1, fin); + int err = fread(&c, 1, 1, fin); if (err==1) { - *pi = (int)c; + *pi = (int)c; return UNZ_OK; } else { - if (ferror(fin)) + if (ferror(fin)) return UNZ_ERRNO; else return UNZ_EOF; } - } - */ +} +*/ /* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets - */ -static int unzlocal_getShort( FILE* fin, uLong *pX ){ - short v; + Reads a long in LSB order from the given gz_stream. Sets +*/ +static int unzlocal_getShort (FILE* fin, uLong *pX) +{ + short v; - fread( &v, sizeof( v ), 1, fin ); + fread( &v, sizeof(v), 1, fin ); - *pX = __LittleShort( v ); + *pX = __LittleShort( v); return UNZ_OK; /* @@ -1238,25 +1257,26 @@ static int unzlocal_getShort( FILE* fin, uLong *pX ){ err = unzlocal_getByte(fin,&i); x = (uLong)i; - + if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; - + if (err==UNZ_OK) - *pX = x; + *pX = x; else - *pX = 0; + *pX = 0; return err; - */ +*/ } -static int unzlocal_getLong( FILE *fin, uLong *pX ){ - int v; +static int unzlocal_getLong (FILE *fin, uLong *pX) +{ + int v; - fread( &v, sizeof( v ), 1, fin ); + fread( &v, sizeof(v), 1, fin ); - *pX = __LittleLong( v ); + *pX = __LittleLong( v); return UNZ_OK; /* @@ -1266,7 +1286,7 @@ static int unzlocal_getLong( FILE *fin, uLong *pX ){ err = unzlocal_getByte(fin,&i); x = (uLong)i; - + if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; @@ -1278,40 +1298,35 @@ static int unzlocal_getLong( FILE *fin, uLong *pX ){ if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<24; - + if (err==UNZ_OK) - *pX = x; + *pX = x; else - *pX = 0; + *pX = 0; return err; - */ +*/ } /* My own strcmpi / strcasecmp */ -static int strcmpcasenosensitive_internal( const char* fileName1,const char* fileName2 ){ - for (;; ) +static int strcmpcasenosensitive_internal (const char* fileName1,const char* fileName2) +{ + for (;;) { - char c1 = *( fileName1++ ); - char c2 = *( fileName2++ ); - if ( ( c1 >= 'a' ) && ( c1 <= 'z' ) ) { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) c1 -= 0x20; - } - if ( ( c2 >= 'a' ) && ( c2 <= 'z' ) ) { + if ((c2>='a') && (c2<='z')) c2 -= 0x20; - } - if ( c1 == '\0' ) { - return ( ( c2 == '\0' ) ? 0 : -1 ); - } - if ( c2 == '\0' ) { + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') return 1; - } - if ( c1 < c2 ) { + if (c1 c2 ) { + if (c1>c2) return 1; - } } } @@ -1326,7 +1341,7 @@ static int strcmpcasenosensitive_internal( const char* fileName1,const char* fil #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal #endif -/* +/* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi @@ -1334,450 +1349,398 @@ static int strcmpcasenosensitive_internal( const char* fileName1,const char* fil If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows) - */ -extern int unzStringFileNameCompare( const char* fileName1,const char* fileName2,int iCaseSensitivity ){ - if ( iCaseSensitivity == 0 ) { - iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; - } +*/ +extern int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity) +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - if ( iCaseSensitivity == 1 ) { - return strcmp( fileName1,fileName2 ); - } + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); - return STRCMPCASENOSENTIVEFUNCTION( fileName1,fileName2 ); -} + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} -#define BUFREADCOMMENT ( 0x400 ) +#define BUFREADCOMMENT (0x400) /* - Locate the Central directory of a zipfile (at the end, just before + Locate the Central directory of a zipfile (at the end, just before the global comment) - */ -static uLong unzlocal_SearchCentralDir( FILE *fin ){ +*/ +static uLong unzlocal_SearchCentralDir(FILE *fin) +{ unsigned char* buf; uLong uSizeFile; uLong uBackRead; - uLong uMaxBack = 0xffff; /* maximum size of global comment */ - uLong uPosFound = 0; - - if ( fseek( fin,0,SEEK_END ) != 0 ) { + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) return 0; - } uSizeFile = ftell( fin ); - - if ( uMaxBack > uSizeFile ) { + + if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; - } - buf = (unsigned char*)malloc( BUFREADCOMMENT + 4 ); - if ( buf == NULL ) { + buf = (unsigned char*)malloc(BUFREADCOMMENT+4); + if (buf==NULL) return 0; - } uBackRead = 4; - while ( uBackRead < uMaxBack ) + while (uBackRead uMaxBack ) { + if (uBackRead+BUFREADCOMMENT>uMaxBack) uBackRead = uMaxBack; - } - else{ - uBackRead += BUFREADCOMMENT; - } - uReadPos = uSizeFile - uBackRead ; - - uReadSize = ( ( BUFREADCOMMENT + 4 ) < ( uSizeFile - uReadPos ) ) ? - ( BUFREADCOMMENT + 4 ) : ( uSizeFile - uReadPos ); - if ( fseek( fin,uReadPos,SEEK_SET ) != 0 ) { + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) break; - } - if ( fread( buf,(uInt)uReadSize,1,fin ) != 1 ) { + if (fread(buf,(uInt)uReadSize,1,fin)!=1) break; - } - for ( i = (int)uReadSize - 3; ( i-- ) > 0; ) - if ( ( ( *( buf + i ) ) == 0x50 ) && ( ( *( buf + i + 1 ) ) == 0x4b ) && - ( ( *( buf + i + 2 ) ) == 0x05 ) && ( ( *( buf + i + 3 ) ) == 0x06 ) ) { - uPosFound = uReadPos + i; + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; break; } - if ( uPosFound != 0 ) { + if (uPosFound!=0) break; - } } - free( buf ); + free(buf); return uPosFound; } -extern unzFile unzReOpen( const char* path, unzFile file ){ +extern unzFile unzReOpen (const char* path, unzFile file) +{ unz_s *s; FILE * fin; - fin = fopen( path,"rb" ); - if ( fin == NULL ) { + fin=fopen(path,"rb"); + if (fin==NULL) return NULL; - } - s = (unz_s*)malloc( sizeof( unz_s ) ); - memcpy( s, (unz_s*)file, sizeof( unz_s ) ); + s=(unz_s*)malloc(sizeof(unz_s)); + memcpy(s, (unz_s*)file, sizeof(unz_s)); s->file = fin; - return (unzFile)s; + return (unzFile)s; } /* - Open a Zip file. path contain the full pathname (by example, + Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer - "zlib/zlib109.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. Else, the return value is a unzFile Handle, usable with other function - of this unzip package. - */ -extern unzFile unzOpen( const char* path ){ + of this unzip package. +*/ +extern unzFile unzOpen (const char* path) +{ unz_s us; unz_s *s; uLong central_pos,uL; FILE * fin ; - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ + for spaning ZIP, unsupported, always 0*/ uLong number_entry_CD; /* total number of entries in - the central dir + the central dir (same than number_entry on nospan) */ - int err = UNZ_OK; + int err=UNZ_OK; - fin = fopen( path,"rb" ); - if ( fin == NULL ) { + fin=fopen(path,"rb"); + if (fin==NULL) return NULL; - } - central_pos = unzlocal_SearchCentralDir( fin ); - if ( central_pos == 0 ) { - err = UNZ_ERRNO; - } + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; - if ( fseek( fin,central_pos,SEEK_SET ) != 0 ) { - err = UNZ_ERRNO; - } + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; /* the signature, already checked */ - if ( unzlocal_getLong( fin,&uL ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; /* number of this disk */ - if ( unzlocal_getShort( fin,&number_disk ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ - if ( unzlocal_getShort( fin,&number_disk_with_CD ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; /* total number of entries in the central dir on this disk */ - if ( unzlocal_getShort( fin,&us.gi.number_entry ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; /* total number of entries in the central dir */ - if ( unzlocal_getShort( fin,&number_entry_CD ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; - if ( ( number_entry_CD != us.gi.number_entry ) || - ( number_disk_with_CD != 0 ) || - ( number_disk != 0 ) ) { - err = UNZ_BADZIPFILE; - } + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; /* size of the central directory */ - if ( unzlocal_getLong( fin,&us.size_central_dir ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; - /* offset of start of central directory with respect to the + /* offset of start of central directory with respect to the starting disk number */ - if ( unzlocal_getLong( fin,&us.offset_central_dir ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; /* zipfile comment length */ - if ( unzlocal_getShort( fin,&us.gi.size_comment ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; - if ( ( central_pos < us.offset_central_dir + us.size_central_dir ) && - ( err == UNZ_OK ) ) { - err = UNZ_BADZIPFILE; - } + if ((central_pospfile_in_zip_read != NULL ) { - unzCloseCurrentFile( file ); - } + if (s->pfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); - fclose( s->file ); - free( s ); + fclose(s->file); + free(s); return UNZ_OK; } /* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int unzGetGlobalInfo( unzFile file,unz_global_info *pglobal_info ){ + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) +{ unz_s* s; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - *pglobal_info = s->gi; + s=(unz_s*)file; + *pglobal_info=s->gi; return UNZ_OK; } /* Translate date/time from Dos format to tm_unz (readable more easilty) - */ -static void unzlocal_DosDateToTmuDate( uLong ulDosDate, tm_unz* ptm ){ - uLong uDate; - uDate = (uLong)( ulDosDate >> 16 ); - ptm->tm_mday = (uInt)( uDate & 0x1f ) ; - ptm->tm_mon = (uInt)( ( ( ( uDate ) & 0x1E0 ) / 0x20 ) - 1 ) ; - ptm->tm_year = (uInt)( ( ( uDate & 0x0FE00 ) / 0x0200 ) + 1980 ) ; +*/ +static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - ptm->tm_hour = (uInt) ( ( ulDosDate & 0xF800 ) / 0x800 ); - ptm->tm_min = (uInt) ( ( ulDosDate & 0x7E0 ) / 0x20 ) ; - ptm->tm_sec = (uInt) ( 2 * ( ulDosDate & 0x1f ) ) ; + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; } /* - Get Info about the current file in the zipfile, with internal only info - */ -static int unzlocal_GetCurrentFileInfoInternal( unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize ){ + Get Info about the current file in the zipfile, with internal only info +*/ +static int unzlocal_GetCurrentFileInfoInternal (unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ unz_s* s; unz_file_info file_info; unz_file_info_internal file_info_internal; - int err = UNZ_OK; + int err=UNZ_OK; uLong uMagic; - long lSeek = 0; + long lSeek=0; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - if ( fseek( s->file,s->pos_in_central_dir + s->byte_before_the_zipfile,SEEK_SET ) != 0 ) { - err = UNZ_ERRNO; - } + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; /* we check the magic */ - if ( err == UNZ_OK ) { - if ( unzlocal_getLong( s->file,&uMagic ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( uMagic != 0x02014b50 ) { - err = UNZ_BADZIPFILE; - } - } + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; - if ( unzlocal_getShort( s->file,&file_info.version ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.version_needed ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.flag ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.compression_method ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.dosDate ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; - unzlocal_DosDateToTmuDate( file_info.dosDate,&file_info.tmu_date ); + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - if ( unzlocal_getLong( s->file,&file_info.crc ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.compressed_size ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.uncompressed_size ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.size_filename ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.size_file_extra ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.size_file_comment ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.disk_num_start ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.internal_fa ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.external_fa ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info_internal.offset_curfile ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; - lSeek += file_info.size_filename; - if ( ( err == UNZ_OK ) && ( szFileName != NULL ) ) { + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { uLong uSizeRead ; - if ( file_info.size_filename < fileNameBufferSize ) { - *( szFileName + file_info.size_filename ) = '\0'; + if (file_info.size_filename 0 ) && ( fileNameBufferSize > 0 ) ) { - if ( fread( szFileName,(uInt)uSizeRead,1,s->file ) != 1 ) { - err = UNZ_ERRNO; - } - } + if ((file_info.size_filename>0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; lSeek -= uSizeRead; } - - if ( ( err == UNZ_OK ) && ( extraField != NULL ) ) { + + if ((err==UNZ_OK) && (extraField!=NULL)) + { uLong uSizeRead ; - if ( file_info.size_file_extra < extraFieldBufferSize ) { + if (file_info.size_file_extrafile,lSeek,SEEK_CUR ) == 0 ) { - lSeek = 0; - } - else{ - err = UNZ_ERRNO; - } - } - if ( ( file_info.size_file_extra > 0 ) && ( extraFieldBufferSize > 0 ) ) { - if ( fread( extraField,(uInt)uSizeRead,1,s->file ) != 1 ) { - err = UNZ_ERRNO; - } - } + if (lSeek!=0) + if (fseek(s->file,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; lSeek += file_info.size_file_extra - uSizeRead; } - else{ - lSeek += file_info.size_file_extra; - } + else + lSeek+=file_info.size_file_extra; - - if ( ( err == UNZ_OK ) && ( szComment != NULL ) ) { + + if ((err==UNZ_OK) && (szComment!=NULL)) + { uLong uSizeRead ; - if ( file_info.size_file_comment < commentBufferSize ) { - *( szComment + file_info.size_file_comment ) = '\0'; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR ) == 0 ) { - lSeek = 0; - } - else{ - err = UNZ_ERRNO; - } - } - if ( ( file_info.size_file_comment > 0 ) && ( commentBufferSize > 0 ) ) { - if ( fread( szComment,(uInt)uSizeRead,1,s->file ) != 1 ) { - err = UNZ_ERRNO; - } - } - lSeek += file_info.size_file_comment - uSizeRead; - } - else{ - lSeek += file_info.size_file_comment; + if (lSeek!=0) + if (fseek(s->file,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; } + else + lSeek+=file_info.size_file_comment; - if ( ( err == UNZ_OK ) && ( pfile_info != NULL ) ) { - *pfile_info = file_info; - } + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; - if ( ( err == UNZ_OK ) && ( pfile_info_internal != NULL ) ) { - *pfile_info_internal = file_info_internal; - } + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; return err; } @@ -1785,118 +1748,114 @@ static int unzlocal_GetCurrentFileInfoInternal( unzFile file, /* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. - */ -extern int unzGetCurrentFileInfo( unzFile file, unz_file_info *pfile_info, - char *szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char *szComment, uLong commentBufferSize ){ - return unzlocal_GetCurrentFileInfoInternal( file,pfile_info,NULL, + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int unzGetCurrentFileInfo ( unzFile file, unz_file_info *pfile_info, + char *szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, - szComment,commentBufferSize ); + szComment,commentBufferSize); } /* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem - */ -extern int unzGoToFirstFile( unzFile file ){ - int err = UNZ_OK; + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; unz_s* s; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - s->pos_in_central_dir = s->offset_central_dir; - s->num_file = 0; - err = unzlocal_GetCurrentFileInfoInternal( file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0 ); - s->current_file_ok = ( err == UNZ_OK ); + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); return err; } /* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. - */ -extern int unzGoToNextFile( unzFile file ){ - unz_s* s; + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int unzGoToNextFile (unzFile file) +{ + unz_s* s; int err; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - if ( !s->current_file_ok ) { + s=(unz_s*)file; + if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; - } - if ( s->num_file + 1 == s->gi.number_entry ) { + if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; - } s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal( file,&s->cur_file_info, + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0 ); - s->current_file_ok = ( err == UNZ_OK ); + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); return err; } /* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found - */ -extern int unzLocateFile( unzFile file, const char *szFileName, int iCaseSensitivity ){ - unz_s* s; + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz_s* s; int err; - + uLong num_fileSaved; uLong pos_in_central_dirSaved; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - if ( strlen( szFileName ) >= UNZ_MAXFILENAMEINZIP ) { - return UNZ_PARAMERROR; - } + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; - s = (unz_s*)file; - if ( !s->current_file_ok ) { + s=(unz_s*)file; + if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; - } num_fileSaved = s->num_file; pos_in_central_dirSaved = s->pos_in_central_dir; - err = unzGoToFirstFile( file ); + err = unzGoToFirstFile(file); - while ( err == UNZ_OK ) + while (err == UNZ_OK) { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1]; - unzGetCurrentFileInfo( file,NULL, - szCurrentFileName,sizeof( szCurrentFileName ) - 1, - NULL,0,NULL,0 ); - if ( unzStringFileNameCompare( szCurrentFileName, - szFileName,iCaseSensitivity ) == 0 ) { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) return UNZ_OK; - } - err = unzGoToNextFile( file ); + err = unzGoToNextFile(file); } s->num_file = num_fileSaved ; @@ -1906,306 +1865,275 @@ extern int unzLocateFile( unzFile file, const char *szFileName, int iCaseSensiti /* - Read the static header of the current zipfile - Check the coherency of the static header and info in the end of central + Read the static header of the current zipfile + Check the coherency of the static header and info in the end of central directory about this file - store in *piSizeVar the size of extra info in static header + store in *piSizeVar the size of extra info in static header (filename and size of extra field data) - */ -static int unzlocal_CheckCurrentFileCoherencyHeader( unz_s* s, uInt* piSizeVar, - uLong *poffset_local_extrafield, - uInt *psize_local_extrafield ){ +*/ +static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, + uLong *poffset_local_extrafield, + uInt *psize_local_extrafield) +{ uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; - int err = UNZ_OK; + int err=UNZ_OK; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; - if ( fseek( s->file,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,SEEK_SET ) != 0 ) { + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; - } - if ( err == UNZ_OK ) { - if ( unzlocal_getLong( s->file,&uMagic ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( uMagic != 0x04034b50 ) { - err = UNZ_BADZIPFILE; - } - } + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; - if ( unzlocal_getShort( s->file,&uData ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; /* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; - */ - if ( unzlocal_getShort( s->file,&uFlags ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - if ( unzlocal_getShort( s->file,&uData ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.compression_method ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; - if ( ( err == UNZ_OK ) && ( s->cur_file_info.compression_method != 0 ) && - ( s->cur_file_info.compression_method != Z_DEFLATED ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* date/time */ - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* crc */ - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.crc ) && - ( ( uFlags & 8 ) == 0 ) ) { - err = UNZ_BADZIPFILE; - } - - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* size compr */ - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.compressed_size ) && - ( ( uFlags & 8 ) == 0 ) ) { - err = UNZ_BADZIPFILE; - } - - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* size uncompr */ - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.uncompressed_size ) && - ( ( uFlags & 8 ) == 0 ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; - if ( unzlocal_getShort( s->file,&size_filename ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( size_filename != s->cur_file_info.size_filename ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; *piSizeVar += (uInt)size_filename; - if ( unzlocal_getShort( s->file,&size_extra_field ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; return err; } - + /* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. - */ -extern int unzOpenCurrentFile( unzFile file ){ - int err = UNZ_OK; + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int unzOpenCurrentFile (unzFile file) +{ + int err=UNZ_OK; int Store; uInt iSizeVar; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uLong offset_local_extrafield; /* offset of the static extra field */ - uInt size_local_extrafield; /* size of the static extra field */ + uInt size_local_extrafield; /* size of the static extra field */ - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - if ( !s->current_file_ok ) { + s=(unz_s*)file; + if (!s->current_file_ok) return UNZ_PARAMERROR; - } - if ( s->pfile_in_zip_read != NULL ) { - unzCloseCurrentFile( file ); - } + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); - if ( unzlocal_CheckCurrentFileCoherencyHeader( s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield ) != UNZ_OK ) { + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) return UNZ_BADZIPFILE; - } pfile_in_zip_read_info = (file_in_zip_read_info_s*) - malloc( sizeof( file_in_zip_read_info_s ) ); - if ( pfile_in_zip_read_info == NULL ) { + malloc(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) return UNZ_INTERNALERROR; - } - pfile_in_zip_read_info->read_buffer = (char*)malloc( UNZ_BUFSIZE ); + pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->pos_local_extrafield=0; - if ( pfile_in_zip_read_info->read_buffer == NULL ) { - free( pfile_in_zip_read_info ); + if (pfile_in_zip_read_info->read_buffer==NULL) + { + free(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } - pfile_in_zip_read_info->stream_initialised = 0; + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; - if ( ( s->cur_file_info.compression_method != 0 ) && - ( s->cur_file_info.compression_method != Z_DEFLATED ) ) { - err = UNZ_BADZIPFILE; - } - Store = s->cur_file_info.compression_method == 0; - - pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; - pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->file = s->file; - pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - pfile_in_zip_read_info->stream.total_out = 0; + pfile_in_zip_read_info->stream.total_out = 0; - if ( !Store ) { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidp)0; - - err = inflateInit2( &pfile_in_zip_read_info->stream, -MAX_WBITS ); - if ( err == Z_OK ) { - pfile_in_zip_read_info->stream_initialised = 1; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidp)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + pfile_in_zip_read_info->stream.avail_in = (uInt)0; s->pfile_in_zip_read = pfile_in_zip_read_info; - return UNZ_OK; + return UNZ_OK; } /* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) - */ -extern int unzReadCurrentFile( unzFile file, void *buf, unsigned len ){ - int err = UNZ_OK; +*/ +extern int unzReadCurrentFile (unzFile file, void *buf, unsigned len) +{ + int err=UNZ_OK; uInt iRead = 0; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } - if ( ( pfile_in_zip_read_info->read_buffer == NULL ) ) { + if ((pfile_in_zip_read_info->read_buffer == NULL)) return UNZ_END_OF_LIST_OF_FILE; - } - if ( len == 0 ) { + if (len==0) return 0; - } pfile_in_zip_read_info->stream.next_out = (Byte*)buf; pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - if ( len > pfile_in_zip_read_info->rest_read_uncompressed ) { - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - } - - while ( pfile_in_zip_read_info->stream.avail_out > 0 ) + while (pfile_in_zip_read_info->stream.avail_out>0) { - if ( ( pfile_in_zip_read_info->stream.avail_in == 0 ) && - ( pfile_in_zip_read_info->rest_read_compressed > 0 ) ) { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { uInt uReadThis = UNZ_BUFSIZE; - if ( pfile_in_zip_read_info->rest_read_compressed < uReadThis ) { + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - } - if ( uReadThis == 0 ) { + if (uReadThis == 0) return UNZ_EOF; - } - if ( s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed ) { - if ( fseek( pfile_in_zip_read_info->file, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET ) != 0 ) { + if (s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed) + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; - } - } - if ( fread( pfile_in_zip_read_info->read_buffer,uReadThis,1, - pfile_in_zip_read_info->file ) != 1 ) { + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; - } pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - pfile_in_zip_read_info->rest_read_compressed -= uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Byte*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Byte*)pfile_in_zip_read_info->read_buffer; pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; } - if ( pfile_in_zip_read_info->compression_method == 0 ) { + if (pfile_in_zip_read_info->compression_method==0) + { uInt uDoCopy,i ; - if ( pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in ) { + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - } - else{ + else uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - } - - for ( i = 0; i < uDoCopy; i++ ) - *( pfile_in_zip_read_info->stream.next_out + i ) = - *( pfile_in_zip_read_info->stream.next_in + i ); - - pfile_in_zip_read_info->crc32 = crc32( pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy ); - pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; pfile_in_zip_read_info->stream.avail_in -= uDoCopy; pfile_in_zip_read_info->stream.avail_out -= uDoCopy; pfile_in_zip_read_info->stream.next_out += uDoCopy; pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; iRead += uDoCopy; } else @@ -2213,391 +2141,367 @@ extern int unzReadCurrentFile( unzFile file, void *buf, unsigned len ){ uLong uTotalOutBefore,uTotalOutAfter; const Byte *bufBefore; uLong uOutThis; - int flush = Z_SYNC_FLUSH; + int flush=Z_SYNC_FLUSH; uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; bufBefore = pfile_in_zip_read_info->stream.next_out; /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == + if ((pfile_in_zip_read_info->rest_read_uncompressed == pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err = inflate( &pfile_in_zip_read_info->stream,flush ); + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter - uTotalOutBefore; - - pfile_in_zip_read_info->crc32 = - crc32( pfile_in_zip_read_info->crc32,bufBefore, - (uInt)( uOutThis ) ); + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; + uOutThis; - iRead += (uInt)( uTotalOutAfter - uTotalOutBefore ); - - if ( err == Z_STREAM_END ) { - return ( iRead == 0 ) ? UNZ_EOF : iRead; - } - if ( err != Z_OK ) { + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) break; - } } } - if ( err == Z_OK ) { + if (err==Z_OK) return iRead; - } return err; } /* - Give the current position in uncompressed data - */ -extern long unztell( unzFile file ){ + Give the current position in uncompressed data +*/ +extern long unztell (unzFile file) +{ unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } return (long)pfile_in_zip_read_info->stream.total_out; } /* - return 1 if the end of file was reached, 0 elsewhere - */ -extern int unzeof( unzFile file ){ + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int unzeof (unzFile file) +{ unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } - - if ( pfile_in_zip_read_info->rest_read_uncompressed == 0 ) { + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) return 1; - } - else{ + else return 0; - } } /* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the static-header version of the extra field (sometimes, there is + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the static-header version of the extra field (sometimes, there is more info in the static-header version than in the central-header) - if buf==NULL, it return the size of the static extra field that can be read + if buf==NULL, it return the size of the static extra field that can be read - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code - */ -extern int unzGetLocalExtrafield( unzFile file,void *buf,unsigned len ){ + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int unzGetLocalExtrafield (unzFile file,void *buf,unsigned len) +{ unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uInt read_now; uLong size_to_read; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } - size_to_read = ( pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield ); + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); - if ( buf == NULL ) { + if (buf==NULL) return (int)size_to_read; - } - - if ( len > size_to_read ) { + + if (len>size_to_read) read_now = (uInt)size_to_read; - } - else{ + else read_now = (uInt)len ; - } - if ( read_now == 0 ) { + if (read_now==0) return 0; - } - - if ( fseek( pfile_in_zip_read_info->file, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET ) != 0 ) { + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) return UNZ_ERRNO; - } - if ( fread( buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file ) != 1 ) { + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; - } return (int)read_now; } /* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good - */ -extern int unzCloseCurrentFile( unzFile file ){ - int err = UNZ_OK; + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; } - if ( pfile_in_zip_read_info->rest_read_uncompressed == 0 ) { - if ( pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait ) { - err = UNZ_CRCERROR; - } - } - - - free( pfile_in_zip_read_info->read_buffer ); + free(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; - if ( pfile_in_zip_read_info->stream_initialised ) { - inflateEnd( &pfile_in_zip_read_info->stream ); - } + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); pfile_in_zip_read_info->stream_initialised = 0; - free( pfile_in_zip_read_info ); + free(pfile_in_zip_read_info); - s->pfile_in_zip_read = NULL; + s->pfile_in_zip_read=NULL; return err; } /* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 - */ -extern int unzGetGlobalComment( unzFile file, char *szComment, uLong uSizeBuf ){ + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) +{ unz_s* s; uLong uReadThis ; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; + s=(unz_s*)file; uReadThis = uSizeBuf; - if ( uReadThis > s->gi.size_comment ) { + if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; - } - if ( fseek( s->file,s->central_pos + 22,SEEK_SET ) != 0 ) { + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) return UNZ_ERRNO; - } - if ( uReadThis > 0 ) { - *szComment = '\0'; - if ( fread( szComment,(uInt)uReadThis,1,s->file ) != 1 ) { - return UNZ_ERRNO; - } - } + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } - if ( ( szComment != NULL ) && ( uSizeBuf > s->gi.size_comment ) ) { - *( szComment + s->gi.size_comment ) = '\0'; - } + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; return (int)uReadThis; } /* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ - #ifdef DYNAMIC_CRC_TABLE static int crc_table_empty = 1; static uLong crc_table[256]; -static void make_crc_table OF( (void) ); +static void make_crc_table OF((void)); /* - Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. - The table is simply the CRC of all possible eight bit values. This is all - the information needed to generate CRC's on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ -static void make_crc_table(){ - uLong c; - int n, k; - uLong poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - /* make exclusive-or pattern from polynomial (0xedb88320L) */ - poly = 0L; - for ( n = 0; n < sizeof( p ) / sizeof( Byte ); n++ ) - poly |= 1L << ( 31 - p[n] ); - - for ( n = 0; n < 256; n++ ) - { - c = (uLong)n; - for ( k = 0; k < 8; k++ ) - c = c & 1 ? poly ^ ( c >> 1 ) : c >> 1; - crc_table[n] = c; - } - crc_table_empty = 0; + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; } #else /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ static const uLong crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL }; #endif /* ========================================================================= * This function can be used by asm versions of crc32() */ -const uLong * get_crc_table(){ +const uLong * get_crc_table() +{ #ifdef DYNAMIC_CRC_TABLE - if ( crc_table_empty ) { - make_crc_table(); - } + if (crc_table_empty) make_crc_table(); #endif - return (const uLong *)crc_table; + return (const uLong *)crc_table; } /* ========================================================================= */ -#define DO1( buf ) crc = crc_table[( (int)crc ^ ( *buf++ ) ) & 0xff] ^ ( crc >> 8 ); -#define DO2( buf ) DO1( buf ); DO1( buf ); -#define DO4( buf ) DO2( buf ); DO2( buf ); -#define DO8( buf ) DO4( buf ); DO4( buf ); +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); /* ========================================================================= */ -uLong crc32( uLong crc, const Byte *buf, uInt len ){ - if ( buf == Z_NULL ) { - return 0L; - } +uLong crc32(uLong crc, const Byte *buf, uInt len) +{ + if (buf == Z_NULL) return 0L; #ifdef DYNAMIC_CRC_TABLE - if ( crc_table_empty ) { - make_crc_table(); - } + if (crc_table_empty) + make_crc_table(); #endif - crc = crc ^ 0xffffffffL; - while ( len >= 8 ) - { - DO8( buf ); - len -= 8; - } - if ( len ) { - do { - DO1( buf ); - } while ( --len ); - } - return crc ^ 0xffffffffL; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; } /* infblock.h -- header to use infblock.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2608,32 +2512,32 @@ uLong crc32( uLong crc, const Byte *buf, uInt len ){ struct inflate_blocks_state; typedef struct inflate_blocks_state inflate_blocks_statef; -extern inflate_blocks_statef * inflate_blocks_new OF( ( - z_streamp z, - check_func c, /* check function */ - uInt w ) ); /* window size */ +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ -extern int inflate_blocks OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); /* initial return code */ +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ -extern void inflate_blocks_reset OF( ( - inflate_blocks_statef *, - z_streamp, - uLong * ) ); /* check value on output */ +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLong *)); /* check value on output */ -extern int inflate_blocks_free OF( ( - inflate_blocks_statef *, - z_streamp ) ); +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); -extern void inflate_set_dictionary OF( ( - inflate_blocks_statef * s, - const Byte * d, /* dictionary */ - uInt n ) ); /* dictionary length */ +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Byte *d, /* dictionary */ + uInt n)); /* dictionary length */ -extern int inflate_blocks_sync_point OF( ( - inflate_blocks_statef * s ) ); +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop @@ -2641,12 +2545,11 @@ extern int inflate_blocks_sync_point OF( ( /* Table for deflate from PKZIP's appnote.txt. */ static const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 -}; + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2660,15 +2563,15 @@ static const uInt border[] = { /* Order of the bit length code lengths */ typedef struct inflate_huft_s inflate_huft; struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit int's) */ - uInt base; /* literal, length base, distance base, - or table offset */ + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ }; /* Maximum size of dynamic tree. The maximum found in a long but non- @@ -2678,35 +2581,35 @@ struct inflate_huft_s { value below is more than safe. */ #define MANY 1440 -extern int inflate_trees_bits OF( ( - uInt *, /* 19 code lengths */ - uInt *, /* bits tree desired/actual depth */ - inflate_huft * *, /* bits tree result */ - inflate_huft *, /* space for trees */ - z_streamp ) ); /* for messages */ +extern int inflate_trees_bits OF(( + uInt *, /* 19 code lengths */ + uInt *, /* bits tree desired/actual depth */ + inflate_huft * *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ -extern int inflate_trees_dynamic OF( ( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uInt *, /* that many (total) code lengths */ - uInt *, /* literal desired/actual bit depth */ - uInt *, /* distance desired/actual bit depth */ - inflate_huft * *, /* literal/length tree result */ - inflate_huft * *, /* distance tree result */ - inflate_huft *, /* space for trees */ - z_streamp ) ); /* for messages */ +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uInt *, /* that many (total) code lengths */ + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft * *, /* literal/length tree result */ + inflate_huft * *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ -extern int inflate_trees_fixed OF( ( - uInt *, /* literal desired/actual bit depth */ - uInt *, /* distance desired/actual bit depth */ - inflate_huft * *, /* literal/length tree result */ - inflate_huft * *, /* distance tree result */ - z_streamp ) ); /* for memory allocation */ +extern int inflate_trees_fixed OF(( + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft * *, /* literal/length tree result */ + inflate_huft * *, /* distance tree result */ + z_streamp)); /* for memory allocation */ /* infcodes.h -- header to use infcodes.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2717,23 +2620,23 @@ extern int inflate_trees_fixed OF( ( struct inflate_codes_state; typedef struct inflate_codes_state inflate_codes_statef; -extern inflate_codes_statef *inflate_codes_new OF( ( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp ) ); +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); -extern int inflate_codes OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); -extern void inflate_codes_free OF( ( - inflate_codes_statef *, - z_streamp ) ); +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); /* infutil.h -- types and macros common to blocks and codes * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2745,76 +2648,75 @@ extern void inflate_codes_free OF( ( #define _INFUTIL_H typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONE, /* finished last block, done */ - BAD -} /* got a data error--stuck here */ + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ inflate_block_mode; /* inflate blocks semi-private state */ struct inflate_blocks_state { - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uInt *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uInt *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - inflate_huft *hufts; /* single malloc for tree space */ - Byte *window; /* sliding window */ - Byte *end; /* one byte after sliding window */ - Byte *read; /* window read pointer */ - Byte *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Byte *window; /* sliding window */ + Byte *end; /* one byte after sliding window */ + Byte *read; /* window read pointer */ + Byte *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ }; /* defines for inflate input/output */ /* update pointers and return */ -#define UPDBITS {s->bitb = b; s->bitk = k; } -#define UPDIN {z->avail_in = n; z->total_in += p - z->next_in; z->next_in = p; } -#define UPDOUT {s->write = q; } +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} #define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush( s,z,r ); } +#define LEAVE {UPDATE return inflate_flush(s,z,r);} /* get bytes and bits */ -#define LOADIN {p = z->next_in; n = z->avail_in; b = s->bitb; k = s->bitk; } -#define NEEDBYTE {if ( n ) {r = Z_OK; }else LEAVE} -#define NEXTBYTE ( n--,*p++ ) -#define NEEDBITS( j ) {while ( k < ( j ) ) {NEEDBYTE; b |= ( (uLong)NEXTBYTE ) << k; k += 8; }} -#define DUMPBITS( j ) {b >>= ( j ); k -= ( j ); } +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} /* output bytes */ -#define WAVAIL (uInt)( q < s->read ? s->read - q - 1 : s->end - q ) -#define LOADOUT {q = s->write; m = (uInt)WAVAIL; } -#define WRAP {if ( q == s->end && s->read != s->window ) {q = s->window; m = (uInt)WAVAIL; }} -#define FLUSH {UPDOUT r = inflate_flush( s,z,r ); LOADOUT} -#define NEEDOUT {if ( m == 0 ) {WRAP if ( m == 0 ) {FLUSH WRAP if ( m == 0 ) {LEAVE}} r = Z_OK; }} -#define OUTBYTE( a ) {*q++ = (Byte)( a ); m--; } +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} /* load static pointers */ #define LOAD {LOADIN LOADOUT} @@ -2822,14 +2724,14 @@ struct inflate_blocks_state { extern uInt inflate_mask[17]; /* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); #endif - + /* Notes beyond the 1.93a appnote.txt: @@ -2862,426 +2764,420 @@ extern int inflate_flush OF( ( (1+6+6). Therefore, to output three times the length, you output three codes (1+1+1), whereas to output four times the same length, you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment + 10. In the tree reconstruction algorithm, Code = Code + Increment only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 really is 258. The last length deserves its own, short code since it gets used a lot in very redundant files. The length 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a + 13. The literal/length and distance code bit lengths are read as a single stream of lengths. It is possible (and advantageous) for a repeat code (16, 17, or 18) to go across the boundary between the two sets of lengths. */ -void inflate_blocks_reset( inflate_blocks_statef *s, z_streamp z, uLong *c ){ - if ( c != Z_NULL ) { - *c = s->check; - } - if ( s->mode == BTREE || s->mode == DTREE ) { - ZFREE( z, s->sub.trees.blens ); - } - if ( s->mode == CODES ) { - inflate_codes_free( s->sub.decode.codes, z ); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if ( s->checkfn != Z_NULL ) { - z->adler = s->check = ( *s->checkfn )( 0L, (const Byte *)Z_NULL, 0 ); - } - Tracev( ( "inflate: blocks reset\n" ) ); +void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c) +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0); + Tracev(("inflate: blocks reset\n")); } -inflate_blocks_statef *inflate_blocks_new( z_streamp z, check_func c, uInt w ){ - inflate_blocks_statef *s; +inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w) +{ + inflate_blocks_statef *s; - if ( ( s = (inflate_blocks_statef *)ZALLOC - ( z,1,sizeof( struct inflate_blocks_state ) ) ) == Z_NULL ) { - return s; - } - if ( ( s->hufts = - (inflate_huft *)ZALLOC( z, sizeof( inflate_huft ), MANY ) ) == Z_NULL ) { - ZFREE( z, s ); - return Z_NULL; - } - if ( ( s->window = (Byte *)ZALLOC( z, 1, w ) ) == Z_NULL ) { - ZFREE( z, s->hufts ); - ZFREE( z, s ); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Tracev( ( "inflate: blocks allocated\n" ) ); - inflate_blocks_reset( s, z, Z_NULL ); - return s; + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev(("inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; } -int inflate_blocks( inflate_blocks_statef *s, z_streamp z, int r ){ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ +int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD - /* process input based on current state */ - while ( 1 ) switch ( s->mode ) - { - case TYPE: - NEEDBITS( 3 ) - t = (uInt)b & 7; - s->last = t & 1; - switch ( t >> 1 ) - { - case 0: /* stored */ - Tracev( ( "inflate: stored block%s\n", - s->last ? " (last)" : "" ) ); - DUMPBITS( 3 ) - t = k & 7; /* go to byte boundary */ - DUMPBITS( t ) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Tracev( ( "inflate: fixed codes block%s\n", - s->last ? " (last)" : "" ) ); - { - uInt bl, bd; - inflate_huft *tl, *td; + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev(("inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev(("inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; - inflate_trees_fixed( &bl, &bd, &tl, &td, z ); - s->sub.decode.codes = inflate_codes_new( bl, bd, tl, td, z ); - if ( s->sub.decode.codes == Z_NULL ) { - r = Z_MEM_ERROR; - LEAVE - } - } - DUMPBITS( 3 ) - s->mode = CODES; - break; - case 2: /* dynamic */ - Tracev( ( "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "" ) ); - DUMPBITS( 3 ) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS( 3 ) - s->mode = BAD; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS( 32 ) - if ( ( ( ( ~b ) >> 16 ) & 0xffff ) != ( b & 0xffff ) ) { - s->mode = BAD; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev( ( "inflate: stored length %u\n", s->sub.left ) ); - s->mode = s->sub.left ? STORED : ( s->last ? DRY : TYPE ); - break; - case STORED: - if ( n == 0 ) { - LEAVE - NEEDOUT - t = s->sub.left; - } - if ( t > n ) { - t = n; - } - if ( t > m ) { - t = m; - } - zmemcpy( q, p, t ); - p += t; n -= t; - q += t; m -= t; - if ( ( s->sub.left -= t ) != 0 ) { - break; - } - Tracev( ( "inflate: stored end, %lu total out\n", - z->total_out + ( q >= s->read ? q - s->read : - ( s->end - s->read ) + ( q - s->window ) ) ) ); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS( 14 ) - s->sub.trees.table = t = (uInt)b & 0x3fff; + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev(("inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev(("inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev(("inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; #ifndef PKZIP_BUG_WORKAROUND - if ( ( t & 0x1f ) > 29 || ( ( t >> 5 ) & 0x1f ) > 29 ) { - s->mode = BAD; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } #endif - t = 258 + ( t & 0x1f ) + ( ( t >> 5 ) & 0x1f ); - if ( ( s->sub.trees.blens = (uInt*)ZALLOC( z, t, sizeof( uInt ) ) ) == Z_NULL ) { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS( 14 ) - s->sub.trees.index = 0; - Tracev( ( "inflate: table sizes ok\n" ) ); - s->mode = BTREE; - case BTREE: - while ( s->sub.trees.index < 4 + ( s->sub.trees.table >> 10 ) ) - { - NEEDBITS( 3 ) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS( 3 ) - } - while ( s->sub.trees.index < 19 ) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits( s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, s->hufts, z ); - if ( t != Z_OK ) { - ZFREE( z, s->sub.trees.blens ); - r = t; - if ( r == Z_DATA_ERROR ) { - s->mode = BAD; - } - LEAVE - } - s->sub.trees.index = 0; - Tracev( ( "inflate: bits tree ok\n" ) ); - s->mode = DTREE; - case DTREE: - while ( t = s->sub.trees.table, - s->sub.trees.index < 258 + ( t & 0x1f ) + ( ( t >> 5 ) & 0x1f ) ) - { - inflate_huft *h; - uInt i, j, c; + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev(("inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + ZFREE(z, s->sub.trees.blens); + r = t; + if (r == Z_DATA_ERROR) + s->mode = BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev(("inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; - t = s->sub.trees.bb; - NEEDBITS( t ) - h = s->sub.trees.tb + ( (uInt)b & inflate_mask[t] ); - t = h->bits; - c = h->base; - if ( c < 16 ) { - DUMPBITS( t ) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS( t + i ) - DUMPBITS( t ) - j += (uInt)b & inflate_mask[i]; - DUMPBITS( i ) - i = s->sub.trees.index; - t = s->sub.trees.table; - if ( i + j > 258 + ( t & 0x1f ) + ( ( t >> 5 ) & 0x1f ) || - ( c == 16 && i < 1 ) ) { - ZFREE( z, s->sub.trees.blens ); - s->mode = BAD; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while ( --j ); - s->sub.trees.index = i; - } - } - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic( 257 + ( t & 0x1f ), 1 + ( ( t >> 5 ) & 0x1f ), - s->sub.trees.blens, &bl, &bd, &tl, &td, - s->hufts, z ); - ZFREE( z, s->sub.trees.blens ); - if ( t != Z_OK ) { - if ( t == (uInt)Z_DATA_ERROR ) { - s->mode = BAD; - } - r = t; - LEAVE - } - Tracev( ( "inflate: trees ok\n" ) ); - if ( ( c = inflate_codes_new( bl, bd, tl, td, z ) ) == Z_NULL ) { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.codes = c; - } - s->mode = CODES; - case CODES: - UPDATE - if ( ( r = inflate_codes( s, z, r ) ) != Z_STREAM_END ) { - return inflate_flush( s, z, r ); - } - r = Z_OK; - inflate_codes_free( s->sub.decode.codes, z ); - LOAD - Tracev( ( "inflate: codes end, %lu total out\n", - z->total_out + ( q >= s->read ? q - s->read : - ( s->end - s->read ) + ( q - s->window ) ) ) ); - if ( !s->last ) { - s->mode = TYPE; - break; - } - s->mode = DRY; - case DRY: - FLUSH - if ( s->read != s->write ) { - LEAVE - s->mode = DONE; - } - case DONE: - r = Z_STREAM_END; - LEAVE - case BAD: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + ZFREE(z, s->sub.trees.blens); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BAD; + r = t; + LEAVE + } + Tracev(("inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev(("inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } } -int inflate_blocks_free( inflate_blocks_statef *s, z_streamp z ){ - inflate_blocks_reset( s, z, Z_NULL ); - ZFREE( z, s->window ); - ZFREE( z, s->hufts ); - ZFREE( z, s ); - Tracev( ( "inflate: blocks freed\n" ) ); - return Z_OK; +int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z) +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev(("inflate: blocks freed\n")); + return Z_OK; } -void inflate_set_dictionary( inflate_blocks_statef *s, const Byte *d, uInt n ){ - zmemcpy( s->window, d, n ); - s->read = s->write = s->window + n; +void inflate_set_dictionary(inflate_blocks_statef *s, const Byte *d, uInt n) +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; } /* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. * IN assertion: s != Z_NULL */ -int inflate_blocks_sync_point( inflate_blocks_statef *s ){ - return s->mode == LENS; +int inflate_blocks_sync_point(inflate_blocks_statef *s) +{ + return s->mode == LENS; } /* And'ing with mask[n] masks the lower n bits */ uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; /* copy as much as possible from the sliding window to the output area */ -int inflate_flush( inflate_blocks_statef *s, z_streamp z, int r ){ - uInt n; - Byte *p; - Byte *q; +int inflate_flush(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt n; + Byte *p; + Byte *q; - /* static copies of source and destination pointers */ - p = z->next_out; - q = s->read; + /* static copies of source and destination pointers */ + p = z->next_out; + q = s->read; - /* compute number of bytes to copy as as end of window */ - n = (uInt)( ( q <= s->write ? s->write : s->end ) - q ); - if ( n > z->avail_out ) { - n = z->avail_out; - } - if ( n && r == Z_BUF_ERROR ) { - r = Z_OK; - } + /* compute number of bytes to copy as as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; - /* update counters */ - z->avail_out -= n; - z->total_out += n; + /* update counters */ + z->avail_out -= n; + z->total_out += n; - /* update check information */ - if ( s->checkfn != Z_NULL ) { - z->adler = s->check = ( *s->checkfn )( s->check, q, n ); - } + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); - /* copy as as end of window */ - zmemcpy( p, q, n ); - p += n; - q += n; + /* copy as as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; - /* see if more to copy at beginning of window */ - if ( q == s->end ) { - /* wrap pointers */ - q = s->window; - if ( s->write == s->end ) { - s->write = s->window; - } + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; - /* compute bytes to copy */ - n = (uInt)( s->write - q ); - if ( n > z->avail_out ) { - n = z->avail_out; - } - if ( n && r == Z_BUF_ERROR ) { - r = Z_OK; - } + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; - /* update counters */ - z->avail_out -= n; - z->total_out += n; + /* update counters */ + z->avail_out -= n; + z->total_out += n; - /* update check information */ - if ( s->checkfn != Z_NULL ) { - z->adler = s->check = ( *s->checkfn )( s->check, q, n ); - } + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); - /* copy */ - zmemcpy( p, q, n ); - p += n; - q += n; - } + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } - /* update pointers */ - z->next_out = p; - s->read = q; + /* update pointers */ + z->next_out = p; + s->read = q; - /* done */ - return r; + /* done */ + return r; } /* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ const char inflate_copyright[] = - " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; + " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; /* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. */ /* simplify the use of the inflate_huft type with some defines */ @@ -3289,38 +3185,34 @@ const char inflate_copyright[] = #define bits word.what.Bits -static int huft_build OF( ( - uInt *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uInt *, /* list of base values for non-simple codes */ - const uInt *, /* list of extra bits for non-simple codes */ - inflate_huft * *, /* result: starting table */ - uInt *, /* maximum lookup bits (returns actual) */ - inflate_huft *, /* space for trees */ - uInt *, /* hufts used in space */ - uInt * ) ); /* space for values */ +static int huft_build OF(( + uInt *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uInt *, /* list of base values for non-simple codes */ + const uInt *, /* list of extra bits for non-simple codes */ + inflate_huft **, /* result: starting table */ + uInt *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uInt * )); /* space for values */ /* Tables for deflate from PKZIP's appnote.txt. */ static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -}; -/* see note #13 above about 258 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 -}; /* 112==invalid */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 -}; + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; static const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13 -}; + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; /* Huffman code decoding is performed using a multi-level table lookup. @@ -3358,7 +3250,7 @@ static const uInt cpdext[30] = { /* Extra bits for distance codes */ /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ #define BMAX 15 /* maximum bit length of any code */ -static int huft_build( uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v ){ +static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v) //uInt *b; /* code lengths in bits (all assumed <= BMAX) */ //uInt n; /* number of codes (assumed <= 288) */ //uInt s; /* number of simple-valued codes (0..s-1) */ @@ -3374,227 +3266,219 @@ static int huft_build( uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, in if the given code set is incomplete (the tables are still built in this case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ - uInt a; /* counter for codes of length k */ - uInt c[BMAX + 1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ - register uInt *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX + 1]; /* bit offsets, then code stack */ - uInt *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uInt *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uInt *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ - /* Generate counts for each bit length */ - p = c; + /* Generate counts for each bit length */ + p = c; #define C0 *p++ = 0; #define C2 C0 C0 C0 C0 #define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while ( --i ); - if ( c[0] == n ) { /* null input--all zero length codes */ - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for ( j = 1; j <= BMAX; j++ ) - if ( c[j] ) { - break; - } - k = j; /* minimum code length */ - if ( (uInt)l < j ) { - l = j; - } - for ( i = BMAX; i; i-- ) - if ( c[i] ) { - break; - } - g = i; /* maximum code length */ - if ( (uInt)l > i ) { - l = i; - } - *m = l; + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; - /* Adjust last length count to fill out codes, if needed */ - for ( y = 1 << j; j < i; j++, y <<= 1 ) - if ( ( y -= c[j] ) < 0 ) { - return Z_DATA_ERROR; - } - if ( ( y -= c[i] ) < 0 ) { - return Z_DATA_ERROR; - } - c[i] += y; + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while ( --i ) { /* note that i == g from above */ - *xp++ = ( j += *p++ ); - } + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ( ( j = *p++ ) != 0 ) { - v[x[j]++] = i; - } - } while ( ++i < n ); - n = x[g]; /* set n to length of v */ + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++ ) - { - a = c[k]; - while ( a-- ) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while ( k > w + l ) - { - h++; - w += l; /* previous table always l bits */ + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ( ( f = 1 << ( j = k - w ) ) > a + 1 ) { /* try a k-w bit table */ - /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if ( j < z ) { - while ( ++j < z ) /* try smaller tables up to z bits */ - { - if ( ( f <<= 1 ) <= *++xp ) { - break; /* enough codes to use up j bits */ - } - f -= *xp; /* else deduct codes from patterns */ - } - } - } - z = 1 << j; /* table entries for j-bit table */ + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ - /* allocate new table */ - if ( *hn + z > MANY ) { /* (note: doesn't matter for fixed) */ - return Z_MEM_ERROR; /* not enough memory */ - } - u[h] = q = hp + *hn; - *hn += z; + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_MEM_ERROR; /* not enough memory */ + u[h] = q = hp + *hn; + *hn += z; - /* connect to last table, if there is one */ - if ( h ) { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - j = i >> ( w - l ); - r.base = (uInt)( q - u[h - 1] - j ); /* offset to this table */ - u[h - 1][j] = r; /* connect to last table */ - } - else{ - *t = q; /* first table is returned result */ - } - } + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } - /* set up table entry in r */ - r.bits = (Byte)( k - w ); - if ( p >= v + n ) { - r.exop = 128 + 64; /* out of values--invalid code */ - } - else if ( *p < s ) { - r.exop = (Byte)( *p < 256 ? 0 : 32 + 64 ); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)( e[*p - s] + 16 + 64 ); /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } - /* fill code-like entries with r */ - f = 1 << ( k - w ); - for ( j = i >> w; j < z; j += f ) - q[j] = r; + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; - /* backwards increment the k-bit code i */ - for ( j = 1 << ( k - 1 ); i &j; j >>= 1 ) - i ^= j; - i ^= j; + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; - /* backup over finished tables */ - mask = ( 1 << w ) - 1; /* needed on HP, cc -O bug */ - while ( ( i & mask ) != x[h] ) - { - h--; /* don't need to update q */ - w -= l; - mask = ( 1 << w ) - 1; - } - } - } + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } -int inflate_trees_bits( uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z ){ +int inflate_trees_bits(uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z) //uInt *c; /* 19 code lengths */ //uInt *bb; /* bits tree desired/actual depth */ //inflate_huft * *tb; /* bits tree result */ //inflate_huft *hp; /* space for trees */ //z_streamp z; /* for messages */ - int r; - uInt hn = 0; /* hufts used in space */ - uInt *v; /* work area for huft_build */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uInt *v; /* work area for huft_build */ - if ( ( v = (uInt*)ZALLOC( z, 19, sizeof( uInt ) ) ) == Z_NULL ) { - return Z_MEM_ERROR; - } - r = huft_build( c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, - tb, bb, hp, &hn, v ); - if ( r == Z_DATA_ERROR ) { - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - } - else if ( r == Z_BUF_ERROR || *bb == 0 ) { - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - ZFREE( z, v ); - return r; + if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; } -int inflate_trees_dynamic( uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z ){ +int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z) //uInt nl; /* number of literal/length codes */ //uInt nd; /* number of distance codes */ //uInt *c; /* that many (total) code lengths */ @@ -3604,55 +3488,57 @@ int inflate_trees_dynamic( uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflat //inflate_huft * *td; /* distance tree result */ //inflate_huft *hp; /* space for trees */ //z_streamp z; /* for messages */ - int r; - uInt hn = 0; /* hufts used in space */ - uInt *v; /* work area for huft_build */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uInt *v; /* work area for huft_build */ - /* allocate work area */ - if ( ( v = (uInt*)ZALLOC( z, 288, sizeof( uInt ) ) ) == Z_NULL ) { - return Z_MEM_ERROR; - } + /* allocate work area */ + if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; - /* build literal/length tree */ - r = huft_build( c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v ); - if ( r != Z_OK || *bl == 0 ) { - if ( r == Z_DATA_ERROR ) { - z->msg = (char*)"oversubscribed literal/length tree"; - } - else if ( r != Z_MEM_ERROR ) { - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - ZFREE( z, v ); - return r; - } + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } - /* build distance tree */ - r = huft_build( c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v ); - if ( r != Z_OK || ( *bd == 0 && nl > 257 ) ) { - if ( r == Z_DATA_ERROR ) { - z->msg = (char*)"oversubscribed distance tree"; - } - else if ( r == Z_BUF_ERROR ) { + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { #ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } + r = Z_OK; + } #else - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if ( r != Z_MEM_ERROR ) { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - ZFREE( z, v ); - return r; + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; #endif - } + } - /* done */ - ZFREE( z, v ); - return Z_OK; + /* done */ + ZFREE(z, v); + return Z_OK; } /* inffixed.h -- table for decoding fixed codes @@ -3667,157 +3553,158 @@ int inflate_trees_dynamic( uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflat static uInt fixed_bl = 9; static uInt fixed_bd = 5; static inflate_huft fixed_tl[] = { - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} -}; + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; static inflate_huft fixed_td[] = { - {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, - {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, - {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, - {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, - {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, - {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, - {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, - {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} -}; + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; -int inflate_trees_fixed( uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z ){ +int inflate_trees_fixed(uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z) //uInt *bl; /* literal desired/actual bit depth */ //uInt *bd; /* distance desired/actual bit depth */ //inflate_huft * *tl; /* literal/length tree result */ //inflate_huft * *td; /* distance tree result */ //z_streamp z; /* for memory allocation */ - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; +{ + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; } /* simplify the use of the inflate_huft type with some defines */ @@ -3825,147 +3712,156 @@ int inflate_trees_fixed( uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS( j ) {while ( k < ( j ) ) {b |= ( (uLong)NEXTBYTE ) << k; k += 8; }} -#define UNGRAB {c = z->avail_in - n; c = ( k >> 3 ) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; } +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} /* Called with number of bytes left to write in window at least 258 (the maximum string length) and number of input bytes available at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer. */ -int inflate_fast( uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z ){ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Byte *r; /* copy source pointer */ +int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z) +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Byte *r; /* copy source pointer */ - /* load input, output, bit values */ - LOAD + /* load input, output, bit values */ + LOAD - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS( 20 ) /* max bits for literal/length code */ - if ( ( e = ( t = tl + ( (uInt)b & ml ) )->exop ) == 0 ) { - DUMPBITS( t->bits ) - Tracevv( ( t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base ) ); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS( t->bits ) - if ( e & 16 ) { - /* get extra bits for length */ - e &= 15; - c = t->base + ( (uInt)b & inflate_mask[e] ); - DUMPBITS( e ) - Tracevv( ( "inflate: * length %u\n", c ) ); + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv(("inflate: * length %u\n", c)); - /* decode distance base of block to copy */ - GRABBITS( 15 ); /* max bits for distance code */ - e = ( t = td + ( (uInt)b & md ) )->exop; - do { - DUMPBITS( t->bits ) - if ( e & 16 ) { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS( e ) /* get extra bits (up to 13) */ - d = t->base + ( (uInt)b & inflate_mask[e] ); - DUMPBITS( e ) - Tracevv( ( "inflate: * distance %u\n", d ) ); + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv(("inflate: * distance %u\n", d)); - /* do the copy */ - m -= c; - if ( (uInt)( q - s->window ) >= d ) { /* offset before dest */ - /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)( q - s->window ); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if ( c > e ) { /* if source crosses, */ - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while ( --e ); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while ( --c ); - break; - } - else if ( ( e & 64 ) == 0 ) { - t += t->base; - e = ( t += ( (uInt)b & inflate_mask[e] ) )->exop; - } - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while ( 1 ); - break; - } - if ( ( e & 64 ) == 0 ) { - t += t->base; - if ( ( e = ( t += ( (uInt)b & inflate_mask[e] ) )->exop ) == 0 ) { - DUMPBITS( t->bits ) - Tracevv( ( t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base ) ); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if ( e & 32 ) { - Tracevv( ( "inflate: * end of block\n" ) ); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while ( 1 ); - } while ( m >= 258 && n >= 10 ); + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (uInt)(q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv(("inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; } /* infcodes.c -- process literals and length/distance pairs * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ @@ -3973,232 +3869,241 @@ int inflate_fast( uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_ #define bits word.what.Bits typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE -} /* x: got error */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ inflate_codes_mode; /* inflate codes private state */ struct inflate_codes_state { - /* mode */ - inflate_codes_mode mode; /* current inflate_codes mode */ + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ }; -inflate_codes_statef *inflate_codes_new( uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z ){ - inflate_codes_statef *c; +inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z) +{ + inflate_codes_statef *c; - if ( ( c = (inflate_codes_statef *) - ZALLOC( z,1,sizeof( struct inflate_codes_state ) ) ) != Z_NULL ) { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev( ( "inflate: codes new\n" ) ); - } - return c; + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev(("inflate: codes new\n")); + } + return c; } -int inflate_codes( inflate_blocks_statef *s, z_streamp z, int r ){ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Byte *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ +int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Byte *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD - /* process input and output based on current state */ - while ( 1 ) switch ( c->mode ) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ #ifndef SLOW - if ( m >= 258 && n >= 10 ) { - UPDATE - r = inflate_fast( c->lbits, c->dbits, c->ltree, c->dtree, s, z ); - LOAD - if ( r != Z_OK ) { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } #endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS( j ) - t = c->sub.code.tree + ( (uInt)b & inflate_mask[j] ); - DUMPBITS( t->bits ) - e = (uInt)( t->exop ); - if ( e == 0 ) { /* literal */ - c->sub.lit = t->base; - Tracevv( ( t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base ) ); - c->mode = LIT; - break; - } - if ( e & 16 ) { /* length */ - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ( ( e & 64 ) == 0 ) { /* next table */ - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - if ( e & 32 ) { /* end of block */ - Tracevv( ( "inflate: end of block\n" ) ); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS( j ) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS( j ) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv( ( "inflate: length %u\n", c->len ) ); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS( j ) - t = c->sub.code.tree + ( (uInt)b & inflate_mask[j] ); - DUMPBITS( t->bits ) - e = (uInt)( t->exop ); - if ( e & 16 ) { /* distance */ - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ( ( e & 64 ) == 0 ) { /* next table */ - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS( j ) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS( j ) - Tracevv( ( "inflate: distance %u\n", c->sub.copy.dist ) ); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv(("inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv(("inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv(("inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ #ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)( q - s->window ) < c->sub.copy.dist ? - s->end - ( c->sub.copy.dist - ( q - s->window ) ) : - q - c->sub.copy.dist; + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; #else - f = q - c->sub.copy.dist; - if ( (uInt)( q - s->window ) < c->sub.copy.dist ) { - f = s->end - ( c->sub.copy.dist - (uInt)( q - s->window ) ); - } + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); #endif - while ( c->len ) - { - NEEDOUT - OUTBYTE( *f++ ) - if ( f == s->end ) { - f = s->window; - } - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE( c->sub.lit ) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - if ( k > 7 ) { /* return unused byte, if any */ - Assert( k < 16, "inflate_codes grabbed too many bytes" ) - k -= 8; - n++; - p--; /* can always return one */ - } - FLUSH - if ( s->read != s->write ) { - LEAVE - c->mode = END; - } - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } #ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } -void inflate_codes_free( inflate_codes_statef *c, z_streamp z ){ - ZFREE( z, c ); - Tracev( ( "inflate: codes free\n" ) ); +void inflate_codes_free(inflate_codes_statef *c, z_streamp z) +{ + ZFREE(z, c); + Tracev(("inflate: codes free\n")); } /* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ #define BASE 65521L /* largest prime smaller than 65536 */ @@ -4210,46 +4115,42 @@ void inflate_codes_free( inflate_codes_statef *c, z_streamp z ){ #undef DO4 #undef DO8 -#define DO1( buf,i ) {s1 += buf[i]; s2 += s1; } -#define DO2( buf,i ) DO1( buf,i ); DO1( buf,i + 1 ); -#define DO4( buf,i ) DO2( buf,i ); DO2( buf,i + 2 ); -#define DO8( buf,i ) DO4( buf,i ); DO4( buf,i + 4 ); -#define DO16( buf ) DO8( buf,0 ); DO8( buf,8 ); +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); /* ========================================================================= */ -uLong adler32( uLong adler, const Byte *buf, uInt len ){ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = ( adler >> 16 ) & 0xffff; - int k; +uLong adler32(uLong adler, const Byte *buf, uInt len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; - if ( buf == Z_NULL ) { - return 1L; - } + if (buf == Z_NULL) return 1L; - while ( len > 0 ) { - k = len < NMAX ? len : NMAX; - len -= k; - while ( k >= 16 ) { - DO16( buf ); - buf += 16; - k -= 16; - } - if ( k != 0 ) { - do { - s1 += *buf++; - s2 += s1; - } while ( --k ); - } - s1 %= BASE; - s2 %= BASE; - } - return ( s2 << 16 ) | s1; + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; } - /* infblock.h -- header to use infblock.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -4257,359 +4158,358 @@ uLong adler32( uLong adler, const Byte *buf, uInt len ){ subject to change. Applications should only use zlib.h. */ -extern inflate_blocks_statef * inflate_blocks_new OF( ( - z_streamp z, - check_func c, /* check function */ - uInt w ) ); /* window size */ +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ -extern int inflate_blocks OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); /* initial return code */ +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ -extern void inflate_blocks_reset OF( ( - inflate_blocks_statef *, - z_streamp, - uLong * ) ); /* check value on output */ +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLong *)); /* check value on output */ -extern int inflate_blocks_free OF( ( - inflate_blocks_statef *, - z_streamp ) ); +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); -extern void inflate_set_dictionary OF( ( - inflate_blocks_statef * s, - const Byte * d, /* dictionary */ - uInt n ) ); /* dictionary length */ +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Byte *d, /* dictionary */ + uInt n)); /* dictionary length */ -extern int inflate_blocks_sync_point OF( ( - inflate_blocks_statef * s ) ); +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); typedef enum { - imMETHOD, /* waiting for method byte */ - imFLAG, /* waiting for flag byte */ - imDICT4, /* four dictionary check bytes to go */ - imDICT3, /* three dictionary check bytes to go */ - imDICT2, /* two dictionary check bytes to go */ - imDICT1, /* one dictionary check byte to go */ - imDICT0, /* waiting for inflateSetDictionary */ - imBLOCKS, /* decompressing blocks */ - imCHECK4, /* four check bytes to go */ - imCHECK3, /* three check bytes to go */ - imCHECK2, /* two check bytes to go */ - imCHECK1, /* one check byte to go */ - imDONE, /* finished check, done */ - imBAD -} /* got an error--stay here */ + imMETHOD, /* waiting for method byte */ + imFLAG, /* waiting for flag byte */ + imDICT4, /* four dictionary check bytes to go */ + imDICT3, /* three dictionary check bytes to go */ + imDICT2, /* two dictionary check bytes to go */ + imDICT1, /* one dictionary check byte to go */ + imDICT0, /* waiting for inflateSetDictionary */ + imBLOCKS, /* decompressing blocks */ + imCHECK4, /* four check bytes to go */ + imCHECK3, /* three check bytes to go */ + imCHECK2, /* two check bytes to go */ + imCHECK1, /* one check byte to go */ + imDONE, /* finished check, done */ + imBAD} /* got an error--stay here */ inflate_mode; /* inflate private state */ struct internal_state { - /* mode */ - inflate_mode mode; /* current inflate mode */ + /* mode */ + inflate_mode mode; /* current inflate mode */ - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ }; -int inflateReset( z_streamp z ){ - if ( z == Z_NULL || z->state == Z_NULL ) { - return Z_STREAM_ERROR; - } - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; - inflate_blocks_reset( z->state->blocks, z, Z_NULL ); - Tracev( ( "inflate: reset\n" ) ); - return Z_OK; +int inflateReset(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev(("inflate: reset\n")); + return Z_OK; } -int inflateEnd( z_streamp z ){ - if ( z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL ) { - return Z_STREAM_ERROR; - } - if ( z->state->blocks != Z_NULL ) { - inflate_blocks_free( z->state->blocks, z ); - } - ZFREE( z, z->state ); - z->state = Z_NULL; - Tracev( ( "inflate: end\n" ) ); - return Z_OK; +int inflateEnd(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev(("inflate: end\n")); + return Z_OK; } -int inflateInit2_( z_streamp z, int w, const char *version, int stream_size ){ - if ( version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof( z_stream ) ) { - return Z_VERSION_ERROR; - } +int inflateInit2_(z_streamp z, int w, const char *version, int stream_size) +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; - /* initialize state */ - if ( z == Z_NULL ) { - return Z_STREAM_ERROR; - } - z->msg = Z_NULL; - if ( z->zalloc == Z_NULL ) { - z->zalloc = ( void *( * )( void *, unsigned, unsigned ) )zcalloc; - z->opaque = (voidp)0; - } - if ( z->zfree == Z_NULL ) { - z->zfree = ( void ( * )( void *, void * ) )zcfree; - } - if ( ( z->state = (struct internal_state *) - ZALLOC( z,1,sizeof( struct internal_state ) ) ) == Z_NULL ) { - return Z_MEM_ERROR; - } - z->state->blocks = Z_NULL; + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = (void *(*)(void *, unsigned, unsigned))zcalloc; + z->opaque = (voidp)0; + } + if (z->zfree == Z_NULL) z->zfree = (void (*)(void *, void *))zcfree; + if ((z->state = (struct internal_state *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if ( w < 0 ) { - w = -w; - z->state->nowrap = 1; - } + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } - /* set window size */ - if ( w < 8 || w > 15 ) { - inflateEnd( z ); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; - /* create inflate_blocks state */ - if ( ( z->state->blocks = - inflate_blocks_new( z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w ) ) - == Z_NULL ) { - inflateEnd( z ); - return Z_MEM_ERROR; - } - Tracev( ( "inflate: allocated\n" ) ); + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev(("inflate: allocated\n")); - /* reset state */ - inflateReset( z ); - return Z_OK; + /* reset state */ + inflateReset(z); + return Z_OK; } -int inflateInit_( z_streamp z, const char *version, int stream_size ){ - return inflateInit2_( z, DEF_WBITS, version, stream_size ); +int inflateInit_(z_streamp z, const char *version, int stream_size) +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); } -#define iNEEDBYTE {if ( z->avail_in == 0 ) {return r; } r = f; } -#define iNEXTBYTE ( z->avail_in--,z->total_in++,*z->next_in++ ) +#define iNEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define iNEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) -int inflate( z_streamp z, int f ){ - int r; - uInt b; +int inflate(z_streamp z, int f) +{ + int r; + uInt b; - if ( z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL ) { - return Z_STREAM_ERROR; - } - f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; - r = Z_BUF_ERROR; - while ( 1 ) switch ( z->state->mode ) - { - case imMETHOD: - iNEEDBYTE - if ( ( ( z->state->sub.method = iNEXTBYTE ) & 0xf ) != Z_DEFLATED ) { - z->state->mode = imBAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ( ( z->state->sub.method >> 4 ) + 8 > z->state->wbits ) { - z->state->mode = imBAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = imFLAG; - case imFLAG: - iNEEDBYTE - b = iNEXTBYTE; - if ( ( ( z->state->sub.method << 8 ) + b ) % 31 ) { - z->state->mode = imBAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Tracev( ( "inflate: zlib header ok\n" ) ); - if ( !( b & PRESET_DICT ) ) { - z->state->mode = imBLOCKS; - break; - } - z->state->mode = imDICT4; - case imDICT4: - iNEEDBYTE - z->state->sub.check.need = (uLong)iNEXTBYTE << 24; - z->state->mode = imDICT3; - case imDICT3: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 16; - z->state->mode = imDICT2; - case imDICT2: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 8; - z->state->mode = imDICT1; - case imDICT1: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = imDICT0; - return Z_NEED_DICT; - case imDICT0: - z->state->mode = imBAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case imBLOCKS: - r = inflate_blocks( z->state->blocks, z, r ); - if ( r == Z_DATA_ERROR ) { - z->state->mode = imBAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if ( r == Z_OK ) { - r = f; - } - if ( r != Z_STREAM_END ) { - return r; - } - r = f; - inflate_blocks_reset( z->state->blocks, z, &z->state->sub.check.was ); - if ( z->state->nowrap ) { - z->state->mode = imDONE; - break; - } - z->state->mode = imCHECK4; - case imCHECK4: - iNEEDBYTE - z->state->sub.check.need = (uLong)iNEXTBYTE << 24; - z->state->mode = imCHECK3; - case imCHECK3: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 16; - z->state->mode = imCHECK2; - case imCHECK2: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 8; - z->state->mode = imCHECK1; - case imCHECK1: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE; + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case imMETHOD: + iNEEDBYTE + if (((z->state->sub.method = iNEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = imBAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = imBAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = imFLAG; + case imFLAG: + iNEEDBYTE + b = iNEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = imBAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev(("inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = imBLOCKS; + break; + } + z->state->mode = imDICT4; + case imDICT4: + iNEEDBYTE + z->state->sub.check.need = (uLong)iNEXTBYTE << 24; + z->state->mode = imDICT3; + case imDICT3: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 16; + z->state->mode = imDICT2; + case imDICT2: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 8; + z->state->mode = imDICT1; + case imDICT1: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = imDICT0; + return Z_NEED_DICT; + case imDICT0: + z->state->mode = imBAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case imBLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = imBAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = imDONE; + break; + } + z->state->mode = imCHECK4; + case imCHECK4: + iNEEDBYTE + z->state->sub.check.need = (uLong)iNEXTBYTE << 24; + z->state->mode = imCHECK3; + case imCHECK3: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 16; + z->state->mode = imCHECK2; + case imCHECK2: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 8; + z->state->mode = imCHECK1; + case imCHECK1: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE; - if ( z->state->sub.check.was != z->state->sub.check.need ) { - z->state->mode = imBAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Tracev( ( "inflate: zlib check ok\n" ) ); - z->state->mode = imDONE; - case imDONE: - return Z_STREAM_END; - case imBAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = imBAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev(("inflate: zlib check ok\n")); + z->state->mode = imDONE; + case imDONE: + return Z_STREAM_END; + case imBAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } #ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } -int inflateSetDictionary( z_streamp z, const Byte *dictionary, uInt dictLength ){ - uInt length = dictLength; +int inflateSetDictionary(z_streamp z, const Byte *dictionary, uInt dictLength) +{ + uInt length = dictLength; - if ( z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0 ) { - return Z_STREAM_ERROR; - } + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0) + return Z_STREAM_ERROR; - if ( adler32( 1L, dictionary, dictLength ) != z->adler ) { - return Z_DATA_ERROR; - } - z->adler = 1L; + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; - if ( length >= ( (uInt)1 << z->state->wbits ) ) { - length = ( 1 << z->state->wbits ) - 1; - dictionary += dictLength - length; - } - inflate_set_dictionary( z->state->blocks, dictionary, length ); - z->state->mode = imBLOCKS; - return Z_OK; + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = imBLOCKS; + return Z_OK; } -int inflateSync( z_streamp z ){ - uInt n; /* number of bytes to look at */ - Byte *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ +int inflateSync(z_streamp z) +{ + uInt n; /* number of bytes to look at */ + Byte *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ - /* set up */ - if ( z == Z_NULL || z->state == Z_NULL ) { - return Z_STREAM_ERROR; - } - if ( z->state->mode != imBAD ) { - z->state->mode = imBAD; - z->state->sub.marker = 0; - } - if ( ( n = z->avail_in ) == 0 ) { - return Z_BUF_ERROR; - } - p = z->next_in; - m = z->state->sub.marker; + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != imBAD) + { + z->state->mode = imBAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; - /* search */ - while ( n && m < 4 ) - { - static const Byte mark[4] = {0, 0, 0xff, 0xff}; - if ( *p == mark[m] ) { - m++; - } - else if ( *p ) { - m = 0; - } - else{ - m = 4 - m; - } - p++, n--; - } + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; - /* return no joy or set up to restart on a new block */ - if ( m != 4 ) { - return Z_DATA_ERROR; - } - r = z->total_in; w = z->total_out; - inflateReset( z ); - z->total_in = r; z->total_out = w; - z->state->mode = imBLOCKS; - return Z_OK; + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = imBLOCKS; + return Z_OK; } @@ -4620,23 +4520,22 @@ int inflateSync( z_streamp z ){ * decompressing, PPP checks that at the end of input packet, inflate is * waiting for these length bytes. */ -int inflateSyncPoint( z_streamp z ){ - if ( z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL ) { - return Z_STREAM_ERROR; - } - return inflate_blocks_sync_point( z->state->blocks ); +int inflateSyncPoint(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); } -voidp zcalloc( voidp opaque, unsigned items, unsigned size ){ - if ( opaque ) { - items += size - size; /* make compiler happy */ - } - return (voidp)malloc( items * size ); +voidp zcalloc (voidp opaque, unsigned items, unsigned size) +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidp)malloc(items*size); } -void zcfree( voidp opaque, voidp ptr ){ - free( ptr ); - if ( opaque ) { - return; /* make compiler happy */ - } +void zcfree (voidp opaque, voidp ptr) +{ + free(ptr); + if (opaque) return; /* make compiler happy */ } + diff --git a/tools/quake3/common/unzip.c b/tools/quake3/common/unzip.c index d90b3523..61598d71 100644 --- a/tools/quake3/common/unzip.c +++ b/tools/quake3/common/unzip.c @@ -1,31 +1,37 @@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. +WARNING: DO NOT UNCRUSTIFY +It will still compile after an uncrustify, but it will be *broken* +See https://github.com/TTimo/GtkRadiant/issues/33 +*/ - This file is part of GtkRadiant. +/* +Copyright (C) 1999-2007 id Software, Inc. and contributors. +For a list of contributors, see the accompanying CONTRIBUTORS file. - GtkRadiant 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 file is part of GtkRadiant. - GtkRadiant 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. +GtkRadiant 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. - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ +GtkRadiant 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 GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ /***************************************************************************** -* name: unzip.c -* -* desc: IO on .zip files using portions of zlib -* -* -*****************************************************************************/ + * name: unzip.c + * + * desc: IO on .zip files using portions of zlib + * + * + *****************************************************************************/ #include #include @@ -35,7 +41,7 @@ // TTimo added for safe_malloc wrapping #include "cmdlib.h" -/* unzip.h -- IO for uncompress .zip files using zlib +/* unzip.h -- IO for uncompress .zip files using zlib Version 0.15 beta, Mar 19th, 1998, Copyright (C) 1998 Gilles Vollant @@ -52,62 +58,62 @@ Condition of use and distribution are the same than zlib : - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. + 3. This notice may not be removed or altered from any source distribution. - */ -/* for more info about .ZIP format, see +*/ +/* for more info about .ZIP format, see ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip PkWare has also a specification at : ftp://ftp.pkware.com/probdesc.zip */ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.1.3, July 9th, 1998 + version 1.1.3, July 9th, 1998 - Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. + 3. This notice may not be removed or altered from any source distribution. - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). - */ + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-1998 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -134,26 +140,26 @@ /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). + Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. - */ + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ -/* Type declarations */ + /* Type declarations */ #ifndef OF /* function prototypes */ -#define OF( args ) args +#define OF(args) args #endif -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ typedef Byte *voidp; #ifndef SEEK_SET @@ -166,26 +172,26 @@ typedef Byte *voidp; #define ZLIB_VERSION "1.1.3" -/* +/* The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio. + with an interface similar to that of stdio. The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. - */ + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ /* The application must update next_in and avail_in when avail_in has @@ -217,9 +223,9 @@ typedef Byte *voidp; the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). - */ +*/ -/* constants */ + /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ @@ -231,12 +237,12 @@ typedef Byte *voidp; #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 -#define Z_ERRNO ( -1 ) -#define Z_STREAM_ERROR ( -2 ) -#define Z_DATA_ERROR ( -3 ) -#define Z_MEM_ERROR ( -4 ) -#define Z_BUF_ERROR ( -5 ) -#define Z_VERSION_ERROR ( -6 ) +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ @@ -244,7 +250,7 @@ typedef Byte *voidp; #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION ( -1 ) +#define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 @@ -265,17 +271,17 @@ typedef Byte *voidp; #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ -/* basic functions */ + /* basic functions */ -const char * zlibVersion OF( (void) ); +const char * zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ -/* - int deflateInit OF((z_streamp strm, int level)); +/* +int deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. @@ -294,88 +300,88 @@ const char * zlibVersion OF( (void) ); with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). - */ +*/ -int deflate OF( ( z_streamp strm, int flush ) ); +int deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. The detailed semantics are as follows. deflate performs one or both of the - following actions: + following actions: - - Compress more input starting at next_in and update next_in and avail_in + - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - the compression. + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read - so (that is, total_in bytes). + so (that is, total_in bytes). deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). - */ + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ -int deflateEnd OF( (z_streamp strm) ); +int deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any @@ -386,11 +392,11 @@ int deflateEnd OF( (z_streamp strm) ); prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). - */ +*/ -/* - int inflateInit OF((z_streamp strm)); +/* +int inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by @@ -407,79 +413,79 @@ int deflateEnd OF( (z_streamp strm) ); message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) - */ +*/ -int inflate OF( ( z_streamp strm, int flush ) ); +int inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may some - introduce some output latency (reading input without producing any output) - except when forced to flush. + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. - The detailed semantics are as follows. inflate performs one or both of the - following actions: + The detailed semantics are as follows. inflate performs one or both of the + following actions: - - Decompress more input starting at next_in and update next_in and avail_in + - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - - Provide more output starting at next_out and update next_out and avail_out + - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much - output as possible to the output buffer. The flushing behavior of inflate is - not specified for values of the flush parameter other than Z_SYNC_FLUSH - and Z_FINISH, but the current implementation actually flushes as much output - as possible anyway. + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. If a preset dictionary is needed at this point (see inflateSetDictionary - below), inflate sets strm-adler to the adler32 checksum of the - dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise - it sets strm->adler to the adler32 checksum of all output produced - so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or - an error code as described below. At the end of the stream, inflate() - checks that its computed adler32 checksum is equal to that saved by the - compressor and returns Z_STREAM_END only if the checksum is correct. + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect - adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent - (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if no progress is possible or if there was not - enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR - case, the application may then call inflateSync to look for a good - compression block. - */ + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ -int inflateEnd OF( (z_streamp strm) ); +int inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any @@ -488,16 +494,16 @@ int inflateEnd OF( (z_streamp strm) ); inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). - */ +*/ -/* Advanced functions */ + /* Advanced functions */ /* The following functions are needed only in some special applications. - */ +*/ -/* - int deflateInit2 OF((z_streamp strm, +/* +int deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, @@ -538,11 +544,11 @@ int inflateEnd OF( (z_streamp strm) ); memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). - */ - -int deflateSetDictionary OF( ( z_streamp strm, - const Byte * dictionary, - uInt dictLength ) ); +*/ + +int deflateSetDictionary OF((z_streamp strm, + const Byte *dictionary, + uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called @@ -574,10 +580,10 @@ int deflateSetDictionary OF( ( z_streamp strm, inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). - */ +*/ -int deflateCopy OF( ( z_streamp dest, - z_streamp source ) ); +int deflateCopy OF((z_streamp dest, + z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. @@ -592,9 +598,9 @@ int deflateCopy OF( ( z_streamp dest, enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. - */ +*/ -int deflateReset OF( (z_streamp strm) ); +int deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. @@ -603,11 +609,11 @@ int deflateReset OF( (z_streamp strm) ); deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). - */ +*/ -int deflateParams OF( ( z_streamp strm, - int level, - int strategy ) ); +int deflateParams OF((z_streamp strm, + int level, + int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be @@ -624,10 +630,10 @@ int deflateParams OF( ( z_streamp strm, deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. - */ +*/ -/* - int inflateInit2 OF((z_streamp strm, +/* +int inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The @@ -647,11 +653,11 @@ int deflateParams OF( ( z_streamp strm, does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) - */ +*/ -int inflateSetDictionary OF( ( z_streamp strm, - const Byte * dictionary, - uInt dictLength ) ); +int inflateSetDictionary OF((z_streamp strm, + const Byte *dictionary, + uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate @@ -666,24 +672,24 @@ int inflateSetDictionary OF( ( z_streamp strm, expected one (incorrect Adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). - */ +*/ -int inflateSync OF( (z_streamp strm) ); -/* +int inflateSync OF((z_streamp strm)); +/* Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. - */ + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ -int inflateReset OF( (z_streamp strm) ); +int inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. @@ -691,10 +697,10 @@ int inflateReset OF( (z_streamp strm) ); inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). - */ +*/ -/* utility functions */ + /* utility functions */ /* The following utility functions are implemented on top of the @@ -702,10 +708,10 @@ int inflateReset OF( (z_streamp strm) ); default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can easily be modified if you need special options. - */ +*/ -int compress OF( ( Byte * dest, uLong * destLen, - const Byte * source, uLong sourceLen ) ); +int compress OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total @@ -717,11 +723,11 @@ int compress OF( ( Byte * dest, uLong * destLen, compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. - */ +*/ -int compress2 OF( ( Byte * dest, uLong * destLen, - const Byte * source, uLong sourceLen, - int level ) ); +int compress2 OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen, + int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -732,10 +738,10 @@ int compress2 OF( ( Byte * dest, uLong * destLen, compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. - */ +*/ -int uncompress OF( ( Byte * dest, uLong * destLen, - const Byte * source, uLong sourceLen ) ); +int uncompress OF((Byte *dest, uLong *destLen, + const Byte *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total @@ -750,12 +756,12 @@ int uncompress OF( ( Byte * dest, uLong * destLen, uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. - */ +*/ typedef voidp gzFile; -gzFile gzopen OF( ( const char *path, const char *mode ) ); +gzFile gzopen OF((const char *path, const char *mode)); /* Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level @@ -771,7 +777,7 @@ gzFile gzopen OF( ( const char *path, const char *mode ) ); can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ -gzFile gzdopen OF( ( int fd, const char *mode ) ); +gzFile gzdopen OF((int fd, const char *mode)); /* gzdopen() associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or @@ -782,17 +788,17 @@ gzFile gzdopen OF( ( int fd, const char *mode ) ); descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). gzdopen returns NULL if there was insufficient memory to allocate the (de)compression state. - */ +*/ -int gzsetparams OF( ( gzFile file, int level, int strategy ) ); +int gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. - */ +*/ -int gzread OF( ( gzFile file, voidp buf, unsigned len ) ); +int gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number @@ -800,50 +806,50 @@ int gzread OF( ( gzFile file, voidp buf, unsigned len ) ); gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error). */ -int gzwrite OF( ( gzFile file, - const voidp buf, unsigned len ) ); +int gzwrite OF((gzFile file, + const voidp buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes actually written (0 in case of error). - */ +*/ -int gzprintf OF( ( gzFile file, const char *format, ... ) ); +int gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). - */ +*/ -int gzputs OF( ( gzFile file, const char *s ) ); +int gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. - */ +*/ -char * gzgets OF( ( gzFile file, char *buf, int len ) ); +char * gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. - */ +*/ -int gzputc OF( ( gzFile file, int c ) ); +int gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. - */ +*/ -int gzgetc OF( (gzFile file) ); +int gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. - */ +*/ -int gzflush OF( ( gzFile file, int flush ) ); +int gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib @@ -851,11 +857,11 @@ int gzflush OF( ( gzFile file, int flush ) ); the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression. - */ +*/ -long gzseek OF( ( gzFile file, - long offset, int whence ) ); -/* +long gzseek OF((gzFile file, + long offset, int whence)); +/* Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); @@ -869,55 +875,55 @@ long gzseek OF( ( gzFile file, the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. - */ +*/ -int gzrewind OF( (gzFile file) ); +int gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) - */ +*/ -long gztell OF( (gzFile file) ); +long gztell OF((gzFile file)); /* Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) - */ +*/ -int gzeof OF( (gzFile file) ); +int gzeof OF((gzFile file)); /* Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. - */ +*/ -int gzclose OF( (gzFile file) ); +int gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below). - */ +*/ -const char * gzerror OF( ( gzFile file, int *errnum ) ); +const char * gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. - */ +*/ -/* checksum functions */ + /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. - */ +*/ -uLong adler32 OF( ( uLong adler, const Byte * buf, uInt len ) ); +uLong adler32 OF((uLong adler, const Byte *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and @@ -932,9 +938,9 @@ uLong adler32 OF( ( uLong adler, const Byte * buf, uInt len ) ); adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); - */ +*/ -uLong crc32 OF( ( uLong crc, const Byte * buf, uInt len ) ); +uLong crc32 OF((uLong crc, const Byte *buf, uInt len)); /* Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value @@ -948,66 +954,72 @@ uLong crc32 OF( ( uLong crc, const Byte * buf, uInt len ) ); crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); - */ +*/ // private stuff to not include cmdlib.h /* - ============================================================================ +============================================================================ - BYTE ORDER FUNCTIONS + BYTE ORDER FUNCTIONS - ============================================================================ - */ +============================================================================ +*/ #ifdef _SGI_SOURCE -#define __BIG_ENDIAN__ +#define __BIG_ENDIAN__ #endif #ifdef __BIG_ENDIAN__ -short __LittleShort( short l ){ - byte b1,b2; +short __LittleShort (short l) +{ + byte b1,b2; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; - return ( b1 << 8 ) + b2; + return (b1<<8) + b2; } -short __BigShort( short l ){ +short __BigShort (short l) +{ return l; } -int __LittleLong( int l ){ - byte b1,b2,b3,b4; +int __LittleLong (int l) +{ + byte b1,b2,b3,b4; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - b3 = ( l >> 16 ) & 255; - b4 = ( l >> 24 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; - return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } -int __BigLong( int l ){ +int __BigLong (int l) +{ return l; } -float __LittleFloat( float l ){ - union {byte b[4]; float f; } in, out; - +float __LittleFloat (float l) +{ + union {byte b[4]; float f;} in, out; + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } -float __BigFloat( float l ){ +float __BigFloat (float l) +{ return l; } @@ -1015,48 +1027,54 @@ float __BigFloat( float l ){ #else -short __BigShort( short l ){ - byte b1,b2; +short __BigShort (short l) +{ + byte b1,b2; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; - return ( b1 << 8 ) + b2; + return (b1<<8) + b2; } -short __LittleShort( short l ){ +short __LittleShort (short l) +{ return l; } -int __BigLong( int l ){ - byte b1,b2,b3,b4; +int __BigLong (int l) +{ + byte b1,b2,b3,b4; - b1 = l & 255; - b2 = ( l >> 8 ) & 255; - b3 = ( l >> 16 ) & 255; - b4 = ( l >> 24 ) & 255; + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; - return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } -int __LittleLong( int l ){ +int __LittleLong (int l) +{ return l; } -float __BigFloat( float l ){ - union {byte b[4]; float f; } in, out; - +float __BigFloat (float l) +{ + union {byte b[4]; float f;} in, out; + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } -float __LittleFloat( float l ){ +float __LittleFloat (float l) +{ return l; } @@ -1067,50 +1085,50 @@ float __LittleFloat( float l ){ -/* various hacks, don't look :) */ + /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ -int deflateInit_ OF( ( z_streamp strm, int level, - const char *version, int stream_size ) ); -int inflateInit_ OF( ( z_streamp strm, - const char *version, int stream_size ) ); -int deflateInit2_ OF( ( z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size ) ); -int inflateInit2_ OF( ( z_streamp strm, int windowBits, - const char *version, int stream_size ) ); -#define deflateInit( strm, level ) \ - deflateInit_( ( strm ), ( level ), ZLIB_VERSION, sizeof( z_stream ) ) -#define inflateInit( strm ) \ - inflateInit_( ( strm ), ZLIB_VERSION, sizeof( z_stream ) ) -#define deflateInit2( strm, level, method, windowBits, memLevel, strategy ) \ - deflateInit2_( ( strm ),( level ),( method ),( windowBits ),( memLevel ), \ - ( strategy ), ZLIB_VERSION, sizeof( z_stream ) ) -#define inflateInit2( strm, windowBits ) \ - inflateInit2_( ( strm ), ( windowBits ), ZLIB_VERSION, sizeof( z_stream ) ) +int deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +int inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +int deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +int inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -const char * zError OF( (int err) ); -int inflateSyncPoint OF( (z_streamp z) ); -const uLong * get_crc_table OF( (void) ); +const char * zError OF((int err)); +int inflateSyncPoint OF((z_streamp z)); +const uLong * get_crc_table OF((void)); -typedef unsigned char uch; +typedef unsigned char uch; typedef unsigned short ush; -typedef unsigned long ulg; +typedef unsigned long ulg; extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG( err ) z_errmsg[Z_NEED_DICT - ( err )] +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] -#define ERR_RETURN( strm,err ) \ - return ( strm->msg = (char*)ERR_MSG( err ), ( err ) ) +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ -/* common constants */ + /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS @@ -1135,84 +1153,84 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ -/* target dependencies */ + /* target dependencies */ -/* Common defaults */ + /* Common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN -# define F_OPEN( name, mode ) fopen( ( name ), ( mode ) ) +# define F_OPEN(name, mode) fopen((name), (mode)) #endif -/* functions */ + /* functions */ #ifdef HAVE_STRERROR -extern char *strerror OF( (int) ); -# define zstrerror( errnum ) strerror( errnum ) + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) #else -# define zstrerror( errnum ) "" +# define zstrerror(errnum) "" #endif #define zmemcpy memcpy #define zmemcmp memcmp -#define zmemzero( dest, len ) memset( dest, 0, len ) +#define zmemzero(dest, len) memset(dest, 0, len) /* Diagnostic functions */ #ifdef _ZIP_DEBUG_ -int z_verbose = 0; -# define Assert( cond,msg ) assert( cond ); -//{if(!(cond)) Sys_Error(msg);} -# define Trace( x ) {if ( z_verbose >= 0 ) {Sys_Error x ; }} -# define Tracev( x ) {if ( z_verbose > 0 ) {Sys_Error x ; }} -# define Tracevv( x ) {if ( z_verbose > 1 ) {Sys_Error x ; }} -# define Tracec( c,x ) {if ( z_verbose > 0 && ( c ) ) {Sys_Error x ; }} -# define Tracecv( c,x ) {if ( z_verbose > 1 && ( c ) ) {Sys_Error x ; }} + int z_verbose = 0; +# define Assert(cond,msg) assert(cond); + //{if(!(cond)) Sys_Error(msg);} +# define Trace(x) {if (z_verbose>=0) Sys_Error x ;} +# define Tracev(x) {if (z_verbose>0) Sys_Error x ;} +# define Tracevv(x) {if (z_verbose>1) Sys_Error x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) Sys_Error x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) Sys_Error x ;} #else -# define Assert( cond,msg ) -# define Trace( x ) -# define Tracev( x ) -# define Tracevv( x ) -# define Tracec( c,x ) -# define Tracecv( c,x ) +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) #endif -typedef uLong ( *check_func ) OF ( ( uLong check, const Byte * buf, uInt len ) ); -voidp zcalloc OF( ( voidp opaque, unsigned items, unsigned size ) ); -void zcfree OF( ( voidp opaque, voidp ptr ) ); +typedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len)); +voidp zcalloc OF((voidp opaque, unsigned items, unsigned size)); +void zcfree OF((voidp opaque, voidp ptr)); -#define ZALLOC( strm, items, size ) \ - ( *( ( strm )->zalloc ) )( ( strm )->opaque, ( items ), ( size ) ) -#define ZFREE( strm, addr ) ( *( ( strm )->zfree ) )( ( strm )->opaque, (voidp)( addr ) ) -#define TRY_FREE( s, p ) {if ( p ) {ZFREE( s, p ); }} +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} -#if !defined( unix ) && !defined( CASESENSITIVITYDEFAULT_YES ) && \ - !defined( CASESENSITIVITYDEFAULT_NO ) +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) #define CASESENSITIVITYDEFAULT_NO #endif #ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE ( 65536 ) +#define UNZ_BUFSIZE (65536) #endif #ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP ( 256 ) +#define UNZ_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC -# define ALLOC( size ) ( safe_malloc( size ) ) +# define ALLOC(size) (safe_malloc(size)) #endif #ifndef TRYFREE -# define TRYFREE( p ) {if ( p ) {free( p ); }} +# define TRYFREE(p) {if (p) free(p);} #endif -#define SIZECENTRALDIRITEM ( 0x2e ) -#define SIZEZIPLOCALHEADER ( 0x1e ) +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) @@ -1220,37 +1238,38 @@ void zcfree OF( ( voidp opaque, voidp ptr ) ); Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading. - */ +*/ /* - static int unzlocal_getByte(FILE *fin,int *pi) - { +static int unzlocal_getByte(FILE *fin,int *pi) +{ unsigned char c; - int err = fread(&c, 1, 1, fin); + int err = fread(&c, 1, 1, fin); if (err==1) { - *pi = (int)c; + *pi = (int)c; return UNZ_OK; } else { - if (ferror(fin)) + if (ferror(fin)) return UNZ_ERRNO; else return UNZ_EOF; } - } - */ +} +*/ /* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets - */ -static int unzlocal_getShort( FILE* fin, uLong *pX ){ - short v; + Reads a long in LSB order from the given gz_stream. Sets +*/ +static int unzlocal_getShort (FILE* fin, uLong *pX) +{ + short v; - fread( &v, sizeof( v ), 1, fin ); + fread( &v, sizeof(v), 1, fin ); - *pX = __LittleShort( v ); + *pX = __LittleShort( v); return UNZ_OK; /* @@ -1260,25 +1279,26 @@ static int unzlocal_getShort( FILE* fin, uLong *pX ){ err = unzlocal_getByte(fin,&i); x = (uLong)i; - + if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; - + if (err==UNZ_OK) - *pX = x; + *pX = x; else - *pX = 0; + *pX = 0; return err; - */ +*/ } -static int unzlocal_getLong( FILE *fin, uLong *pX ){ - int v; +static int unzlocal_getLong (FILE *fin, uLong *pX) +{ + int v; - fread( &v, sizeof( v ), 1, fin ); + fread( &v, sizeof(v), 1, fin ); - *pX = __LittleLong( v ); + *pX = __LittleLong( v); return UNZ_OK; /* @@ -1288,7 +1308,7 @@ static int unzlocal_getLong( FILE *fin, uLong *pX ){ err = unzlocal_getByte(fin,&i); x = (uLong)i; - + if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; @@ -1300,40 +1320,35 @@ static int unzlocal_getLong( FILE *fin, uLong *pX ){ if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<24; - + if (err==UNZ_OK) - *pX = x; + *pX = x; else - *pX = 0; + *pX = 0; return err; - */ +*/ } /* My own strcmpi / strcasecmp */ -static int strcmpcasenosensitive_internal( const char* fileName1,const char* fileName2 ){ - for (;; ) +static int strcmpcasenosensitive_internal (const char* fileName1,const char* fileName2) +{ + for (;;) { - char c1 = *( fileName1++ ); - char c2 = *( fileName2++ ); - if ( ( c1 >= 'a' ) && ( c1 <= 'z' ) ) { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) c1 -= 0x20; - } - if ( ( c2 >= 'a' ) && ( c2 <= 'z' ) ) { + if ((c2>='a') && (c2<='z')) c2 -= 0x20; - } - if ( c1 == '\0' ) { - return ( ( c2 == '\0' ) ? 0 : -1 ); - } - if ( c2 == '\0' ) { + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') return 1; - } - if ( c1 < c2 ) { + if (c1 c2 ) { + if (c1>c2) return 1; - } } } @@ -1348,7 +1363,7 @@ static int strcmpcasenosensitive_internal( const char* fileName1,const char* fil #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal #endif -/* +/* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi @@ -1356,450 +1371,398 @@ static int strcmpcasenosensitive_internal( const char* fileName1,const char* fil If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows) - */ -extern int unzStringFileNameCompare( const char* fileName1,const char* fileName2,int iCaseSensitivity ){ - if ( iCaseSensitivity == 0 ) { - iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; - } +*/ +extern int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity) +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - if ( iCaseSensitivity == 1 ) { - return strcmp( fileName1,fileName2 ); - } + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); - return STRCMPCASENOSENTIVEFUNCTION( fileName1,fileName2 ); -} + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} -#define BUFREADCOMMENT ( 0x400 ) +#define BUFREADCOMMENT (0x400) /* - Locate the Central directory of a zipfile (at the end, just before + Locate the Central directory of a zipfile (at the end, just before the global comment) - */ -static uLong unzlocal_SearchCentralDir( FILE *fin ){ +*/ +static uLong unzlocal_SearchCentralDir(FILE *fin) +{ unsigned char* buf; uLong uSizeFile; uLong uBackRead; - uLong uMaxBack = 0xffff; /* maximum size of global comment */ - uLong uPosFound = 0; - - if ( fseek( fin,0,SEEK_END ) != 0 ) { + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) return 0; - } uSizeFile = ftell( fin ); - - if ( uMaxBack > uSizeFile ) { + + if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; - } - buf = (unsigned char*)safe_malloc( BUFREADCOMMENT + 4 ); - if ( buf == NULL ) { + buf = (unsigned char*)safe_malloc(BUFREADCOMMENT+4); + if (buf==NULL) return 0; - } uBackRead = 4; - while ( uBackRead < uMaxBack ) + while (uBackRead uMaxBack ) { + if (uBackRead+BUFREADCOMMENT>uMaxBack) uBackRead = uMaxBack; - } - else{ - uBackRead += BUFREADCOMMENT; - } - uReadPos = uSizeFile - uBackRead ; - - uReadSize = ( ( BUFREADCOMMENT + 4 ) < ( uSizeFile - uReadPos ) ) ? - ( BUFREADCOMMENT + 4 ) : ( uSizeFile - uReadPos ); - if ( fseek( fin,uReadPos,SEEK_SET ) != 0 ) { + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) break; - } - if ( fread( buf,(uInt)uReadSize,1,fin ) != 1 ) { + if (fread(buf,(uInt)uReadSize,1,fin)!=1) break; - } - for ( i = (int)uReadSize - 3; ( i-- ) > 0; ) - if ( ( ( *( buf + i ) ) == 0x50 ) && ( ( *( buf + i + 1 ) ) == 0x4b ) && - ( ( *( buf + i + 2 ) ) == 0x05 ) && ( ( *( buf + i + 3 ) ) == 0x06 ) ) { - uPosFound = uReadPos + i; + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; break; } - if ( uPosFound != 0 ) { + if (uPosFound!=0) break; - } } - free( buf ); + free(buf); return uPosFound; } -extern unzFile unzReOpen( const char* path, unzFile file ){ +extern unzFile unzReOpen (const char* path, unzFile file) +{ unz_s *s; FILE * fin; - fin = fopen( path,"rb" ); - if ( fin == NULL ) { + fin=fopen(path,"rb"); + if (fin==NULL) return NULL; - } - s = (unz_s*)safe_malloc( sizeof( unz_s ) ); - memcpy( s, (unz_s*)file, sizeof( unz_s ) ); + s=(unz_s*)safe_malloc(sizeof(unz_s)); + memcpy(s, (unz_s*)file, sizeof(unz_s)); s->file = fin; - return (unzFile)s; + return (unzFile)s; } /* - Open a Zip file. path contain the full pathname (by example, + Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer - "zlib/zlib109.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. Else, the return value is a unzFile Handle, usable with other function - of this unzip package. - */ -extern unzFile unzOpen( const char* path ){ + of this unzip package. +*/ +extern unzFile unzOpen (const char* path) +{ unz_s us; unz_s *s; uLong central_pos,uL; FILE * fin ; - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ + for spaning ZIP, unsupported, always 0*/ uLong number_entry_CD; /* total number of entries in - the central dir + the central dir (same than number_entry on nospan) */ - int err = UNZ_OK; + int err=UNZ_OK; - fin = fopen( path,"rb" ); - if ( fin == NULL ) { + fin=fopen(path,"rb"); + if (fin==NULL) return NULL; - } - central_pos = unzlocal_SearchCentralDir( fin ); - if ( central_pos == 0 ) { - err = UNZ_ERRNO; - } + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; - if ( fseek( fin,central_pos,SEEK_SET ) != 0 ) { - err = UNZ_ERRNO; - } + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; /* the signature, already checked */ - if ( unzlocal_getLong( fin,&uL ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; /* number of this disk */ - if ( unzlocal_getShort( fin,&number_disk ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ - if ( unzlocal_getShort( fin,&number_disk_with_CD ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; /* total number of entries in the central dir on this disk */ - if ( unzlocal_getShort( fin,&us.gi.number_entry ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; /* total number of entries in the central dir */ - if ( unzlocal_getShort( fin,&number_entry_CD ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; - if ( ( number_entry_CD != us.gi.number_entry ) || - ( number_disk_with_CD != 0 ) || - ( number_disk != 0 ) ) { - err = UNZ_BADZIPFILE; - } + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; /* size of the central directory */ - if ( unzlocal_getLong( fin,&us.size_central_dir ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; - /* offset of start of central directory with respect to the + /* offset of start of central directory with respect to the starting disk number */ - if ( unzlocal_getLong( fin,&us.offset_central_dir ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; /* zipfile comment length */ - if ( unzlocal_getShort( fin,&us.gi.size_comment ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; - if ( ( central_pos < us.offset_central_dir + us.size_central_dir ) && - ( err == UNZ_OK ) ) { - err = UNZ_BADZIPFILE; - } + if ((central_pospfile_in_zip_read != NULL ) { - unzCloseCurrentFile( file ); - } + if (s->pfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); - fclose( s->file ); - free( s ); + fclose(s->file); + free(s); return UNZ_OK; } /* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int unzGetGlobalInfo( unzFile file,unz_global_info *pglobal_info ){ + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) +{ unz_s* s; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - *pglobal_info = s->gi; + s=(unz_s*)file; + *pglobal_info=s->gi; return UNZ_OK; } /* Translate date/time from Dos format to tm_unz (readable more easilty) - */ -static void unzlocal_DosDateToTmuDate( uLong ulDosDate, tm_unz* ptm ){ - uLong uDate; - uDate = (uLong)( ulDosDate >> 16 ); - ptm->tm_mday = (uInt)( uDate & 0x1f ) ; - ptm->tm_mon = (uInt)( ( ( ( uDate ) & 0x1E0 ) / 0x20 ) - 1 ) ; - ptm->tm_year = (uInt)( ( ( uDate & 0x0FE00 ) / 0x0200 ) + 1980 ) ; +*/ +static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - ptm->tm_hour = (uInt) ( ( ulDosDate & 0xF800 ) / 0x800 ); - ptm->tm_min = (uInt) ( ( ulDosDate & 0x7E0 ) / 0x20 ) ; - ptm->tm_sec = (uInt) ( 2 * ( ulDosDate & 0x1f ) ) ; + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; } /* - Get Info about the current file in the zipfile, with internal only info - */ -static int unzlocal_GetCurrentFileInfoInternal( unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize ){ + Get Info about the current file in the zipfile, with internal only info +*/ +static int unzlocal_GetCurrentFileInfoInternal (unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ unz_s* s; unz_file_info file_info; unz_file_info_internal file_info_internal; - int err = UNZ_OK; + int err=UNZ_OK; uLong uMagic; - long lSeek = 0; + long lSeek=0; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - if ( fseek( s->file,s->pos_in_central_dir + s->byte_before_the_zipfile,SEEK_SET ) != 0 ) { - err = UNZ_ERRNO; - } + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; /* we check the magic */ - if ( err == UNZ_OK ) { - if ( unzlocal_getLong( s->file,&uMagic ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( uMagic != 0x02014b50 ) { - err = UNZ_BADZIPFILE; - } - } + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; - if ( unzlocal_getShort( s->file,&file_info.version ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.version_needed ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.flag ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.compression_method ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.dosDate ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; - unzlocal_DosDateToTmuDate( file_info.dosDate,&file_info.tmu_date ); + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - if ( unzlocal_getLong( s->file,&file_info.crc ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.compressed_size ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.uncompressed_size ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.size_filename ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.size_file_extra ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.size_file_comment ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.disk_num_start ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getShort( s->file,&file_info.internal_fa ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info.external_fa ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; - if ( unzlocal_getLong( s->file,&file_info_internal.offset_curfile ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; - lSeek += file_info.size_filename; - if ( ( err == UNZ_OK ) && ( szFileName != NULL ) ) { + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { uLong uSizeRead ; - if ( file_info.size_filename < fileNameBufferSize ) { - *( szFileName + file_info.size_filename ) = '\0'; + if (file_info.size_filename 0 ) && ( fileNameBufferSize > 0 ) ) { - if ( fread( szFileName,(uInt)uSizeRead,1,s->file ) != 1 ) { - err = UNZ_ERRNO; - } - } + if ((file_info.size_filename>0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; lSeek -= uSizeRead; } - - if ( ( err == UNZ_OK ) && ( extraField != NULL ) ) { + + if ((err==UNZ_OK) && (extraField!=NULL)) + { uLong uSizeRead ; - if ( file_info.size_file_extra < extraFieldBufferSize ) { + if (file_info.size_file_extrafile,lSeek,SEEK_CUR ) == 0 ) { - lSeek = 0; - } - else{ - err = UNZ_ERRNO; - } - } - if ( ( file_info.size_file_extra > 0 ) && ( extraFieldBufferSize > 0 ) ) { - if ( fread( extraField,(uInt)uSizeRead,1,s->file ) != 1 ) { - err = UNZ_ERRNO; - } - } + if (lSeek!=0) + if (fseek(s->file,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; lSeek += file_info.size_file_extra - uSizeRead; } - else{ - lSeek += file_info.size_file_extra; - } + else + lSeek+=file_info.size_file_extra; - - if ( ( err == UNZ_OK ) && ( szComment != NULL ) ) { + + if ((err==UNZ_OK) && (szComment!=NULL)) + { uLong uSizeRead ; - if ( file_info.size_file_comment < commentBufferSize ) { - *( szComment + file_info.size_file_comment ) = '\0'; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR ) == 0 ) { - lSeek = 0; - } - else{ - err = UNZ_ERRNO; - } - } - if ( ( file_info.size_file_comment > 0 ) && ( commentBufferSize > 0 ) ) { - if ( fread( szComment,(uInt)uSizeRead,1,s->file ) != 1 ) { - err = UNZ_ERRNO; - } - } - lSeek += file_info.size_file_comment - uSizeRead; - } - else{ - lSeek += file_info.size_file_comment; + if (lSeek!=0) + if (fseek(s->file,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; } + else + lSeek+=file_info.size_file_comment; - if ( ( err == UNZ_OK ) && ( pfile_info != NULL ) ) { - *pfile_info = file_info; - } + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; - if ( ( err == UNZ_OK ) && ( pfile_info_internal != NULL ) ) { - *pfile_info_internal = file_info_internal; - } + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; return err; } @@ -1807,118 +1770,114 @@ static int unzlocal_GetCurrentFileInfoInternal( unzFile file, /* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. - */ -extern int unzGetCurrentFileInfo( unzFile file, unz_file_info *pfile_info, - char *szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char *szComment, uLong commentBufferSize ){ - return unzlocal_GetCurrentFileInfoInternal( file,pfile_info,NULL, + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int unzGetCurrentFileInfo ( unzFile file, unz_file_info *pfile_info, + char *szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, - szComment,commentBufferSize ); + szComment,commentBufferSize); } /* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem - */ -extern int unzGoToFirstFile( unzFile file ){ - int err = UNZ_OK; + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; unz_s* s; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - s->pos_in_central_dir = s->offset_central_dir; - s->num_file = 0; - err = unzlocal_GetCurrentFileInfoInternal( file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0 ); - s->current_file_ok = ( err == UNZ_OK ); + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); return err; } /* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. - */ -extern int unzGoToNextFile( unzFile file ){ - unz_s* s; + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int unzGoToNextFile (unzFile file) +{ + unz_s* s; int err; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - if ( !s->current_file_ok ) { + s=(unz_s*)file; + if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; - } - if ( s->num_file + 1 == s->gi.number_entry ) { + if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; - } s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal( file,&s->cur_file_info, + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0 ); - s->current_file_ok = ( err == UNZ_OK ); + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); return err; } /* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found - */ -extern int unzLocateFile( unzFile file, const char *szFileName, int iCaseSensitivity ){ - unz_s* s; + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz_s* s; int err; - + uLong num_fileSaved; uLong pos_in_central_dirSaved; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - if ( strlen( szFileName ) >= UNZ_MAXFILENAMEINZIP ) { - return UNZ_PARAMERROR; - } + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; - s = (unz_s*)file; - if ( !s->current_file_ok ) { + s=(unz_s*)file; + if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; - } num_fileSaved = s->num_file; pos_in_central_dirSaved = s->pos_in_central_dir; - err = unzGoToFirstFile( file ); + err = unzGoToFirstFile(file); - while ( err == UNZ_OK ) + while (err == UNZ_OK) { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1]; - unzGetCurrentFileInfo( file,NULL, - szCurrentFileName,sizeof( szCurrentFileName ) - 1, - NULL,0,NULL,0 ); - if ( unzStringFileNameCompare( szCurrentFileName, - szFileName,iCaseSensitivity ) == 0 ) { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) return UNZ_OK; - } - err = unzGoToNextFile( file ); + err = unzGoToNextFile(file); } s->num_file = num_fileSaved ; @@ -1928,306 +1887,275 @@ extern int unzLocateFile( unzFile file, const char *szFileName, int iCaseSensiti /* - Read the static header of the current zipfile - Check the coherency of the static header and info in the end of central + Read the static header of the current zipfile + Check the coherency of the static header and info in the end of central directory about this file - store in *piSizeVar the size of extra info in static header + store in *piSizeVar the size of extra info in static header (filename and size of extra field data) - */ -static int unzlocal_CheckCurrentFileCoherencyHeader( unz_s* s, uInt* piSizeVar, - uLong *poffset_local_extrafield, - uInt *psize_local_extrafield ){ +*/ +static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, + uLong *poffset_local_extrafield, + uInt *psize_local_extrafield) +{ uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; - int err = UNZ_OK; + int err=UNZ_OK; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; - if ( fseek( s->file,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,SEEK_SET ) != 0 ) { + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; - } - if ( err == UNZ_OK ) { - if ( unzlocal_getLong( s->file,&uMagic ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( uMagic != 0x04034b50 ) { - err = UNZ_BADZIPFILE; - } - } + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; - if ( unzlocal_getShort( s->file,&uData ) != UNZ_OK ) { - err = UNZ_ERRNO; - } + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; /* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; - */ - if ( unzlocal_getShort( s->file,&uFlags ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - if ( unzlocal_getShort( s->file,&uData ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.compression_method ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; - if ( ( err == UNZ_OK ) && ( s->cur_file_info.compression_method != 0 ) && - ( s->cur_file_info.compression_method != Z_DEFLATED ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* date/time */ - err = UNZ_ERRNO; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* crc */ - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.crc ) && - ( ( uFlags & 8 ) == 0 ) ) { - err = UNZ_BADZIPFILE; - } - - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* size compr */ - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.compressed_size ) && - ( ( uFlags & 8 ) == 0 ) ) { - err = UNZ_BADZIPFILE; - } - - if ( unzlocal_getLong( s->file,&uData ) != UNZ_OK ) { /* size uncompr */ - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( uData != s->cur_file_info.uncompressed_size ) && - ( ( uFlags & 8 ) == 0 ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; - if ( unzlocal_getShort( s->file,&size_filename ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - else if ( ( err == UNZ_OK ) && ( size_filename != s->cur_file_info.size_filename ) ) { - err = UNZ_BADZIPFILE; - } + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; *piSizeVar += (uInt)size_filename; - if ( unzlocal_getShort( s->file,&size_extra_field ) != UNZ_OK ) { - err = UNZ_ERRNO; - } - *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; return err; } - + /* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. - */ -extern int unzOpenCurrentFile( unzFile file ){ - int err = UNZ_OK; + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int unzOpenCurrentFile (unzFile file) +{ + int err=UNZ_OK; int Store; uInt iSizeVar; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uLong offset_local_extrafield; /* offset of the static extra field */ - uInt size_local_extrafield; /* size of the static extra field */ + uInt size_local_extrafield; /* size of the static extra field */ - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - if ( !s->current_file_ok ) { + s=(unz_s*)file; + if (!s->current_file_ok) return UNZ_PARAMERROR; - } - if ( s->pfile_in_zip_read != NULL ) { - unzCloseCurrentFile( file ); - } + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); - if ( unzlocal_CheckCurrentFileCoherencyHeader( s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield ) != UNZ_OK ) { + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) return UNZ_BADZIPFILE; - } pfile_in_zip_read_info = (file_in_zip_read_info_s*) - safe_malloc( sizeof( file_in_zip_read_info_s ) ); - if ( pfile_in_zip_read_info == NULL ) { + safe_malloc(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) return UNZ_INTERNALERROR; - } - pfile_in_zip_read_info->read_buffer = (char*)safe_malloc( UNZ_BUFSIZE ); + pfile_in_zip_read_info->read_buffer=(char*)safe_malloc(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->pos_local_extrafield=0; - if ( pfile_in_zip_read_info->read_buffer == NULL ) { - free( pfile_in_zip_read_info ); + if (pfile_in_zip_read_info->read_buffer==NULL) + { + free(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } - pfile_in_zip_read_info->stream_initialised = 0; + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; - if ( ( s->cur_file_info.compression_method != 0 ) && - ( s->cur_file_info.compression_method != Z_DEFLATED ) ) { - err = UNZ_BADZIPFILE; - } - Store = s->cur_file_info.compression_method == 0; - - pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; - pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->file = s->file; - pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - pfile_in_zip_read_info->stream.total_out = 0; + pfile_in_zip_read_info->stream.total_out = 0; - if ( !Store ) { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidp)0; - - err = inflateInit2( &pfile_in_zip_read_info->stream, -MAX_WBITS ); - if ( err == Z_OK ) { - pfile_in_zip_read_info->stream_initialised = 1; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidp)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + pfile_in_zip_read_info->stream.avail_in = (uInt)0; s->pfile_in_zip_read = pfile_in_zip_read_info; - return UNZ_OK; + return UNZ_OK; } /* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) - */ -extern int unzReadCurrentFile( unzFile file, void *buf, unsigned len ){ - int err = UNZ_OK; +*/ +extern int unzReadCurrentFile (unzFile file, void *buf, unsigned len) +{ + int err=UNZ_OK; uInt iRead = 0; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } - if ( ( pfile_in_zip_read_info->read_buffer == NULL ) ) { + if ((pfile_in_zip_read_info->read_buffer == NULL)) return UNZ_END_OF_LIST_OF_FILE; - } - if ( len == 0 ) { + if (len==0) return 0; - } pfile_in_zip_read_info->stream.next_out = (Byte*)buf; pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - if ( len > pfile_in_zip_read_info->rest_read_uncompressed ) { - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - } - - while ( pfile_in_zip_read_info->stream.avail_out > 0 ) + while (pfile_in_zip_read_info->stream.avail_out>0) { - if ( ( pfile_in_zip_read_info->stream.avail_in == 0 ) && - ( pfile_in_zip_read_info->rest_read_compressed > 0 ) ) { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { uInt uReadThis = UNZ_BUFSIZE; - if ( pfile_in_zip_read_info->rest_read_compressed < uReadThis ) { + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - } - if ( uReadThis == 0 ) { + if (uReadThis == 0) return UNZ_EOF; - } - if ( s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed ) { - if ( fseek( pfile_in_zip_read_info->file, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET ) != 0 ) { + if (s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed) + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; - } - } - if ( fread( pfile_in_zip_read_info->read_buffer,uReadThis,1, - pfile_in_zip_read_info->file ) != 1 ) { + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; - } pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - pfile_in_zip_read_info->rest_read_compressed -= uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Byte*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Byte*)pfile_in_zip_read_info->read_buffer; pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; } - if ( pfile_in_zip_read_info->compression_method == 0 ) { + if (pfile_in_zip_read_info->compression_method==0) + { uInt uDoCopy,i ; - if ( pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in ) { + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - } - else{ + else uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - } - - for ( i = 0; i < uDoCopy; i++ ) - *( pfile_in_zip_read_info->stream.next_out + i ) = - *( pfile_in_zip_read_info->stream.next_in + i ); - - pfile_in_zip_read_info->crc32 = crc32( pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy ); - pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; pfile_in_zip_read_info->stream.avail_in -= uDoCopy; pfile_in_zip_read_info->stream.avail_out -= uDoCopy; pfile_in_zip_read_info->stream.next_out += uDoCopy; pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; iRead += uDoCopy; } else @@ -2235,232 +2163,213 @@ extern int unzReadCurrentFile( unzFile file, void *buf, unsigned len ){ uLong uTotalOutBefore,uTotalOutAfter; const Byte *bufBefore; uLong uOutThis; - int flush = Z_SYNC_FLUSH; + int flush=Z_SYNC_FLUSH; uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; bufBefore = pfile_in_zip_read_info->stream.next_out; /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == + if ((pfile_in_zip_read_info->rest_read_uncompressed == pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err = inflate( &pfile_in_zip_read_info->stream,flush ); + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter - uTotalOutBefore; - - pfile_in_zip_read_info->crc32 = - crc32( pfile_in_zip_read_info->crc32,bufBefore, - (uInt)( uOutThis ) ); + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; + uOutThis; - iRead += (uInt)( uTotalOutAfter - uTotalOutBefore ); - - if ( err == Z_STREAM_END ) { - return ( iRead == 0 ) ? UNZ_EOF : iRead; - } - if ( err != Z_OK ) { + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) break; - } } } - if ( err == Z_OK ) { + if (err==Z_OK) return iRead; - } return err; } /* - Give the current position in uncompressed data - */ -extern long unztell( unzFile file ){ + Give the current position in uncompressed data +*/ +extern long unztell (unzFile file) +{ unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } return (long)pfile_in_zip_read_info->stream.total_out; } /* - return 1 if the end of file was reached, 0 elsewhere - */ -extern int unzeof( unzFile file ){ + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int unzeof (unzFile file) +{ unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } - - if ( pfile_in_zip_read_info->rest_read_uncompressed == 0 ) { + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) return 1; - } - else{ + else return 0; - } } /* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the static-header version of the extra field (sometimes, there is + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the static-header version of the extra field (sometimes, there is more info in the static-header version than in the central-header) - if buf==NULL, it return the size of the static extra field that can be read + if buf==NULL, it return the size of the static extra field that can be read - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code - */ -extern int unzGetLocalExtrafield( unzFile file,void *buf,unsigned len ){ + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int unzGetLocalExtrafield (unzFile file,void *buf,unsigned len) +{ unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uInt read_now; uLong size_to_read; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; - } - size_to_read = ( pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield ); + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); - if ( buf == NULL ) { + if (buf==NULL) return (int)size_to_read; - } - - if ( len > size_to_read ) { + + if (len>size_to_read) read_now = (uInt)size_to_read; - } - else{ + else read_now = (uInt)len ; - } - if ( read_now == 0 ) { + if (read_now==0) return 0; - } - - if ( fseek( pfile_in_zip_read_info->file, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET ) != 0 ) { + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) return UNZ_ERRNO; - } - if ( fread( buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file ) != 1 ) { + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; - } return (int)read_now; } /* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good - */ -extern int unzCloseCurrentFile( unzFile file ){ - int err = UNZ_OK; + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; - pfile_in_zip_read_info = s->pfile_in_zip_read; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; - if ( pfile_in_zip_read_info == NULL ) { + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; } - if ( pfile_in_zip_read_info->rest_read_uncompressed == 0 ) { - if ( pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait ) { - err = UNZ_CRCERROR; - } - } - - - free( pfile_in_zip_read_info->read_buffer ); + free(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; - if ( pfile_in_zip_read_info->stream_initialised ) { - inflateEnd( &pfile_in_zip_read_info->stream ); - } + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); pfile_in_zip_read_info->stream_initialised = 0; - free( pfile_in_zip_read_info ); + free(pfile_in_zip_read_info); - s->pfile_in_zip_read = NULL; + s->pfile_in_zip_read=NULL; return err; } /* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 - */ -extern int unzGetGlobalComment( unzFile file, char *szComment, uLong uSizeBuf ){ + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) +{ unz_s* s; uLong uReadThis ; - if ( file == NULL ) { + if (file==NULL) return UNZ_PARAMERROR; - } - s = (unz_s*)file; + s=(unz_s*)file; uReadThis = uSizeBuf; - if ( uReadThis > s->gi.size_comment ) { + if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; - } - if ( fseek( s->file,s->central_pos + 22,SEEK_SET ) != 0 ) { + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) return UNZ_ERRNO; - } - if ( uReadThis > 0 ) { - *szComment = '\0'; - if ( fread( szComment,(uInt)uReadThis,1,s->file ) != 1 ) { - return UNZ_ERRNO; - } - } + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } - if ( ( szComment != NULL ) && ( uSizeBuf > s->gi.size_comment ) ) { - *( szComment + s->gi.size_comment ) = '\0'; - } + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; return (int)uReadThis; } /* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -2468,110 +2377,111 @@ extern int unzGetGlobalComment( unzFile file, char *szComment, uLong uSizeBuf ){ static int crc_table_empty = 1; static uLong crc_table[256]; -static void make_crc_table OF( (void) ); +static void make_crc_table OF((void)); /* - Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. - The table is simply the CRC of all possible eight bit values. This is all - the information needed to generate CRC's on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ -static void make_crc_table(){ - uLong c; - int n, k; - uLong poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - /* make exclusive-or pattern from polynomial (0xedb88320L) */ - poly = 0L; - for ( n = 0; n < sizeof( p ) / sizeof( Byte ); n++ ) - poly |= 1L << ( 31 - p[n] ); - - for ( n = 0; n < 256; n++ ) - { - c = (uLong)n; - for ( k = 0; k < 8; k++ ) - c = c & 1 ? poly ^ ( c >> 1 ) : c >> 1; - crc_table[n] = c; - } - crc_table_empty = 0; + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; } #else /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ static const uLong crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL }; #endif @@ -2579,51 +2489,46 @@ static const uLong crc_table[256] = { * This function can be used by asm versions of crc32() */ #ifndef __APPLE__ -const uLong * get_crc_table(){ +const uLong * get_crc_table() +{ #ifdef DYNAMIC_CRC_TABLE - if ( crc_table_empty ) { - make_crc_table(); - } + if (crc_table_empty) make_crc_table(); #endif - return (const uLong *)crc_table; + return (const uLong *)crc_table; } #endif /* ========================================================================= */ -#define DO1( buf ) crc = crc_table[( (int)crc ^ ( *buf++ ) ) & 0xff] ^ ( crc >> 8 ); -#define DO2( buf ) DO1( buf ); DO1( buf ); -#define DO4( buf ) DO2( buf ); DO2( buf ); -#define DO8( buf ) DO4( buf ); DO4( buf ); +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); /* ========================================================================= */ #ifndef __APPLE__ -uLong crc32( uLong crc, const Byte *buf, uInt len ){ - if ( buf == Z_NULL ) { - return 0L; - } +uLong crc32(uLong crc, const Byte *buf, uInt len) +{ + if (buf == Z_NULL) return 0L; #ifdef DYNAMIC_CRC_TABLE - if ( crc_table_empty ) { - make_crc_table(); - } + if (crc_table_empty) + make_crc_table(); #endif - crc = crc ^ 0xffffffffL; - while ( len >= 8 ) - { - DO8( buf ); - len -= 8; - } - if ( len ) { - do { - DO1( buf ); - } while ( --len ); - } - return crc ^ 0xffffffffL; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; } #endif /* infblock.h -- header to use infblock.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2634,32 +2539,32 @@ uLong crc32( uLong crc, const Byte *buf, uInt len ){ struct inflate_blocks_state; typedef struct inflate_blocks_state inflate_blocks_statef; -extern inflate_blocks_statef * inflate_blocks_new OF( ( - z_streamp z, - check_func c, /* check function */ - uInt w ) ); /* window size */ +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ -extern int inflate_blocks OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); /* initial return code */ +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ -extern void inflate_blocks_reset OF( ( - inflate_blocks_statef *, - z_streamp, - uLong * ) ); /* check value on output */ +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLong *)); /* check value on output */ -extern int inflate_blocks_free OF( ( - inflate_blocks_statef *, - z_streamp ) ); +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); -extern void inflate_set_dictionary OF( ( - inflate_blocks_statef * s, - const Byte * d, /* dictionary */ - uInt n ) ); /* dictionary length */ +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Byte *d, /* dictionary */ + uInt n)); /* dictionary length */ -extern int inflate_blocks_sync_point OF( ( - inflate_blocks_statef * s ) ); +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop @@ -2667,12 +2572,11 @@ extern int inflate_blocks_sync_point OF( ( /* Table for deflate from PKZIP's appnote.txt. */ static const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 -}; + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2686,15 +2590,15 @@ static const uInt border[] = { /* Order of the bit length code lengths */ typedef struct inflate_huft_s inflate_huft; struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit int's) */ - uInt base; /* literal, length base, distance base, - or table offset */ + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ }; /* Maximum size of dynamic tree. The maximum found in a long but non- @@ -2704,35 +2608,35 @@ struct inflate_huft_s { value below is more than safe. */ #define MANY 1440 -extern int inflate_trees_bits OF( ( - uInt *, /* 19 code lengths */ - uInt *, /* bits tree desired/actual depth */ - inflate_huft * *, /* bits tree result */ - inflate_huft *, /* space for trees */ - z_streamp ) ); /* for messages */ +extern int inflate_trees_bits OF(( + uInt *, /* 19 code lengths */ + uInt *, /* bits tree desired/actual depth */ + inflate_huft * *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ -extern int inflate_trees_dynamic OF( ( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uInt *, /* that many (total) code lengths */ - uInt *, /* literal desired/actual bit depth */ - uInt *, /* distance desired/actual bit depth */ - inflate_huft * *, /* literal/length tree result */ - inflate_huft * *, /* distance tree result */ - inflate_huft *, /* space for trees */ - z_streamp ) ); /* for messages */ +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uInt *, /* that many (total) code lengths */ + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft * *, /* literal/length tree result */ + inflate_huft * *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ -extern int inflate_trees_fixed OF( ( - uInt *, /* literal desired/actual bit depth */ - uInt *, /* distance desired/actual bit depth */ - inflate_huft * *, /* literal/length tree result */ - inflate_huft * *, /* distance tree result */ - z_streamp ) ); /* for memory allocation */ +extern int inflate_trees_fixed OF(( + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft * *, /* literal/length tree result */ + inflate_huft * *, /* distance tree result */ + z_streamp)); /* for memory allocation */ /* infcodes.h -- header to use infcodes.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2743,23 +2647,23 @@ extern int inflate_trees_fixed OF( ( struct inflate_codes_state; typedef struct inflate_codes_state inflate_codes_statef; -extern inflate_codes_statef *inflate_codes_new OF( ( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp ) ); +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); -extern int inflate_codes OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); -extern void inflate_codes_free OF( ( - inflate_codes_statef *, - z_streamp ) ); +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); /* infutil.h -- types and macros common to blocks and codes * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -2771,76 +2675,75 @@ extern void inflate_codes_free OF( ( #define _INFUTIL_H typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONE, /* finished last block, done */ - BAD -} /* got a data error--stuck here */ + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ inflate_block_mode; /* inflate blocks semi-private state */ struct inflate_blocks_state { - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uInt *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uInt *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - inflate_huft *hufts; /* single safe_malloc for tree space */ - Byte *window; /* sliding window */ - Byte *end; /* one byte after sliding window */ - Byte *read; /* window read pointer */ - Byte *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single safe_malloc for tree space */ + Byte *window; /* sliding window */ + Byte *end; /* one byte after sliding window */ + Byte *read; /* window read pointer */ + Byte *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ }; /* defines for inflate input/output */ /* update pointers and return */ -#define UPDBITS {s->bitb = b; s->bitk = k; } -#define UPDIN {z->avail_in = n; z->total_in += p - z->next_in; z->next_in = p; } -#define UPDOUT {s->write = q; } +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} #define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush( s,z,r ); } +#define LEAVE {UPDATE return inflate_flush(s,z,r);} /* get bytes and bits */ -#define LOADIN {p = z->next_in; n = z->avail_in; b = s->bitb; k = s->bitk; } -#define NEEDBYTE {if ( n ) {r = Z_OK; }else LEAVE} -#define NEXTBYTE ( n--,*p++ ) -#define NEEDBITS( j ) {while ( k < ( j ) ) {NEEDBYTE; b |= ( (uLong)NEXTBYTE ) << k; k += 8; }} -#define DUMPBITS( j ) {b >>= ( j ); k -= ( j ); } +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} /* output bytes */ -#define WAVAIL (uInt)( q < s->read ? s->read - q - 1 : s->end - q ) -#define LOADOUT {q = s->write; m = (uInt)WAVAIL; } -#define WRAP {if ( q == s->end && s->read != s->window ) {q = s->window; m = (uInt)WAVAIL; }} -#define FLUSH {UPDOUT r = inflate_flush( s,z,r ); LOADOUT} -#define NEEDOUT {if ( m == 0 ) {WRAP if ( m == 0 ) {FLUSH WRAP if ( m == 0 ) {LEAVE}} r = Z_OK; }} -#define OUTBYTE( a ) {*q++ = (Byte)( a ); m--; } +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} /* load static pointers */ #define LOAD {LOADIN LOADOUT} @@ -2848,14 +2751,14 @@ struct inflate_blocks_state { extern uInt inflate_mask[17]; /* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); #endif - + /* Notes beyond the 1.93a appnote.txt: @@ -2888,14 +2791,14 @@ extern int inflate_flush OF( ( (1+6+6). Therefore, to output three times the length, you output three codes (1+1+1), whereas to output four times the same length, you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment + 10. In the tree reconstruction algorithm, Code = Code + Increment only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 really is 258. The last length deserves its own, short code since it gets used a lot in very redundant files. The length 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a + 13. The literal/length and distance code bit lengths are read as a single stream of lengths. It is possible (and advantageous) for a repeat code (16, 17, or 18) to go across the boundary between the two sets of lengths. @@ -2903,423 +2806,417 @@ extern int inflate_flush OF( ( #ifndef __APPLE__ -void inflate_blocks_reset( inflate_blocks_statef *s, z_streamp z, uLong *c ){ - if ( c != Z_NULL ) { - *c = s->check; - } - if ( s->mode == BTREE || s->mode == DTREE ) { - ZFREE( z, s->sub.trees.blens ); - } - if ( s->mode == CODES ) { - inflate_codes_free( s->sub.decode.codes, z ); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if ( s->checkfn != Z_NULL ) { - z->adler = s->check = ( *s->checkfn )( 0L, (const Byte *)Z_NULL, 0 ); - } - Tracev( ( "inflate: blocks reset\n" ) ); +void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c) +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0); + Tracev(("inflate: blocks reset\n")); } #endif #ifndef __APPLE__ -inflate_blocks_statef *inflate_blocks_new( z_streamp z, check_func c, uInt w ){ - inflate_blocks_statef *s; +inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w) +{ + inflate_blocks_statef *s; - if ( ( s = (inflate_blocks_statef *)ZALLOC - ( z,1,sizeof( struct inflate_blocks_state ) ) ) == Z_NULL ) { - return s; - } - if ( ( s->hufts = - (inflate_huft *)ZALLOC( z, sizeof( inflate_huft ), MANY ) ) == Z_NULL ) { - ZFREE( z, s ); - return Z_NULL; - } - if ( ( s->window = (Byte *)ZALLOC( z, 1, w ) ) == Z_NULL ) { - ZFREE( z, s->hufts ); - ZFREE( z, s ); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Tracev( ( "inflate: blocks allocated\n" ) ); - inflate_blocks_reset( s, z, Z_NULL ); - return s; + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev(("inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; } #endif #ifndef __APPLE__ -int inflate_blocks( inflate_blocks_statef *s, z_streamp z, int r ){ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ +int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD - /* process input based on current state */ - while ( 1 ) switch ( s->mode ) - { - case TYPE: - NEEDBITS( 3 ) - t = (uInt)b & 7; - s->last = t & 1; - switch ( t >> 1 ) - { - case 0: /* stored */ - Tracev( ( "inflate: stored block%s\n", - s->last ? " (last)" : "" ) ); - DUMPBITS( 3 ) - t = k & 7; /* go to byte boundary */ - DUMPBITS( t ) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Tracev( ( "inflate: fixed codes block%s\n", - s->last ? " (last)" : "" ) ); - { - uInt bl, bd; - inflate_huft *tl, *td; + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev(("inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev(("inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; - inflate_trees_fixed( &bl, &bd, &tl, &td, z ); - s->sub.decode.codes = inflate_codes_new( bl, bd, tl, td, z ); - if ( s->sub.decode.codes == Z_NULL ) { - r = Z_MEM_ERROR; - LEAVE - } - } - DUMPBITS( 3 ) - s->mode = CODES; - break; - case 2: /* dynamic */ - Tracev( ( "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "" ) ); - DUMPBITS( 3 ) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS( 3 ) - s->mode = BAD; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS( 32 ) - if ( ( ( ( ~b ) >> 16 ) & 0xffff ) != ( b & 0xffff ) ) { - s->mode = BAD; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev( ( "inflate: stored length %u\n", s->sub.left ) ); - s->mode = s->sub.left ? STORED : ( s->last ? DRY : TYPE ); - break; - case STORED: - if ( n == 0 ) { - LEAVE - NEEDOUT - t = s->sub.left; - } - if ( t > n ) { - t = n; - } - if ( t > m ) { - t = m; - } - zmemcpy( q, p, t ); - p += t; n -= t; - q += t; m -= t; - if ( ( s->sub.left -= t ) != 0 ) { - break; - } - Tracev( ( "inflate: stored end, %lu total out\n", - z->total_out + ( q >= s->read ? q - s->read : - ( s->end - s->read ) + ( q - s->window ) ) ) ); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS( 14 ) - s->sub.trees.table = t = (uInt)b & 0x3fff; + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev(("inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev(("inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev(("inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; #ifndef PKZIP_BUG_WORKAROUND - if ( ( t & 0x1f ) > 29 || ( ( t >> 5 ) & 0x1f ) > 29 ) { - s->mode = BAD; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } #endif - t = 258 + ( t & 0x1f ) + ( ( t >> 5 ) & 0x1f ); - if ( ( s->sub.trees.blens = (uInt*)ZALLOC( z, t, sizeof( uInt ) ) ) == Z_NULL ) { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS( 14 ) - s->sub.trees.index = 0; - Tracev( ( "inflate: table sizes ok\n" ) ); - s->mode = BTREE; - case BTREE: - while ( s->sub.trees.index < 4 + ( s->sub.trees.table >> 10 ) ) - { - NEEDBITS( 3 ) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS( 3 ) - } - while ( s->sub.trees.index < 19 ) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits( s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, s->hufts, z ); - if ( t != Z_OK ) { - ZFREE( z, s->sub.trees.blens ); - r = t; - if ( r == Z_DATA_ERROR ) { - s->mode = BAD; - } - LEAVE - } - s->sub.trees.index = 0; - Tracev( ( "inflate: bits tree ok\n" ) ); - s->mode = DTREE; - case DTREE: - while ( t = s->sub.trees.table, - s->sub.trees.index < 258 + ( t & 0x1f ) + ( ( t >> 5 ) & 0x1f ) ) - { - inflate_huft *h; - uInt i, j, c; + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev(("inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + ZFREE(z, s->sub.trees.blens); + r = t; + if (r == Z_DATA_ERROR) + s->mode = BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev(("inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; - t = s->sub.trees.bb; - NEEDBITS( t ) - h = s->sub.trees.tb + ( (uInt)b & inflate_mask[t] ); - t = h->bits; - c = h->base; - if ( c < 16 ) { - DUMPBITS( t ) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS( t + i ) - DUMPBITS( t ) - j += (uInt)b & inflate_mask[i]; - DUMPBITS( i ) - i = s->sub.trees.index; - t = s->sub.trees.table; - if ( i + j > 258 + ( t & 0x1f ) + ( ( t >> 5 ) & 0x1f ) || - ( c == 16 && i < 1 ) ) { - ZFREE( z, s->sub.trees.blens ); - s->mode = BAD; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while ( --j ); - s->sub.trees.index = i; - } - } - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic( 257 + ( t & 0x1f ), 1 + ( ( t >> 5 ) & 0x1f ), - s->sub.trees.blens, &bl, &bd, &tl, &td, - s->hufts, z ); - ZFREE( z, s->sub.trees.blens ); - if ( t != Z_OK ) { - if ( t == (uInt)Z_DATA_ERROR ) { - s->mode = BAD; - } - r = t; - LEAVE - } - Tracev( ( "inflate: trees ok\n" ) ); - if ( ( c = inflate_codes_new( bl, bd, tl, td, z ) ) == Z_NULL ) { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.codes = c; - } - s->mode = CODES; - case CODES: - UPDATE - if ( ( r = inflate_codes( s, z, r ) ) != Z_STREAM_END ) { - return inflate_flush( s, z, r ); - } - r = Z_OK; - inflate_codes_free( s->sub.decode.codes, z ); - LOAD - Tracev( ( "inflate: codes end, %lu total out\n", - z->total_out + ( q >= s->read ? q - s->read : - ( s->end - s->read ) + ( q - s->window ) ) ) ); - if ( !s->last ) { - s->mode = TYPE; - break; - } - s->mode = DRY; - case DRY: - FLUSH - if ( s->read != s->write ) { - LEAVE - s->mode = DONE; - } - case DONE: - r = Z_STREAM_END; - LEAVE - case BAD: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + ZFREE(z, s->sub.trees.blens); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BAD; + r = t; + LEAVE + } + Tracev(("inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev(("inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } } #endif #ifndef __APPLE__ -int inflate_blocks_free( inflate_blocks_statef *s, z_streamp z ){ - inflate_blocks_reset( s, z, Z_NULL ); - ZFREE( z, s->window ); - ZFREE( z, s->hufts ); - ZFREE( z, s ); - Tracev( ( "inflate: blocks freed\n" ) ); - return Z_OK; +int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z) +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev(("inflate: blocks freed\n")); + return Z_OK; } #endif #ifndef __APPLE__ -void inflate_set_dictionary( inflate_blocks_statef *s, const Byte *d, uInt n ){ - zmemcpy( s->window, d, n ); - s->read = s->write = s->window + n; +void inflate_set_dictionary(inflate_blocks_statef *s, const Byte *d, uInt n) +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; } #endif /* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. * IN assertion: s != Z_NULL */ #ifndef __APPLE__ -int inflate_blocks_sync_point( inflate_blocks_statef *s ){ - return s->mode == LENS; +int inflate_blocks_sync_point(inflate_blocks_statef *s) +{ + return s->mode == LENS; } #endif /* And'ing with mask[n] masks the lower n bits */ uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; /* copy as much as possible from the sliding window to the output area */ #ifndef __APPLE__ -int inflate_flush( inflate_blocks_statef *s, z_streamp z, int r ){ - uInt n; - Byte *p; - Byte *q; +int inflate_flush(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt n; + Byte *p; + Byte *q; - /* static copies of source and destination pointers */ - p = z->next_out; - q = s->read; + /* static copies of source and destination pointers */ + p = z->next_out; + q = s->read; - /* compute number of bytes to copy as as end of window */ - n = (uInt)( ( q <= s->write ? s->write : s->end ) - q ); - if ( n > z->avail_out ) { - n = z->avail_out; - } - if ( n && r == Z_BUF_ERROR ) { - r = Z_OK; - } + /* compute number of bytes to copy as as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; - /* update counters */ - z->avail_out -= n; - z->total_out += n; + /* update counters */ + z->avail_out -= n; + z->total_out += n; - /* update check information */ - if ( s->checkfn != Z_NULL ) { - z->adler = s->check = ( *s->checkfn )( s->check, q, n ); - } + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); - /* copy as as end of window */ - zmemcpy( p, q, n ); - p += n; - q += n; + /* copy as as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; - /* see if more to copy at beginning of window */ - if ( q == s->end ) { - /* wrap pointers */ - q = s->window; - if ( s->write == s->end ) { - s->write = s->window; - } + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; - /* compute bytes to copy */ - n = (uInt)( s->write - q ); - if ( n > z->avail_out ) { - n = z->avail_out; - } - if ( n && r == Z_BUF_ERROR ) { - r = Z_OK; - } + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; - /* update counters */ - z->avail_out -= n; - z->total_out += n; + /* update counters */ + z->avail_out -= n; + z->total_out += n; - /* update check information */ - if ( s->checkfn != Z_NULL ) { - z->adler = s->check = ( *s->checkfn )( s->check, q, n ); - } + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); - /* copy */ - zmemcpy( p, q, n ); - p += n; - q += n; - } + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } - /* update pointers */ - z->next_out = p; - s->read = q; + /* update pointers */ + z->next_out = p; + s->read = q; - /* done */ - return r; + /* done */ + return r; } #endif /* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ #ifndef __APPLE__ const char inflate_copyright[] = - " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; + " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; #endif /* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. */ /* simplify the use of the inflate_huft type with some defines */ @@ -3327,38 +3224,34 @@ const char inflate_copyright[] = #define bits word.what.Bits -static int huft_build OF( ( - uInt *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uInt *, /* list of base values for non-simple codes */ - const uInt *, /* list of extra bits for non-simple codes */ - inflate_huft * *, /* result: starting table */ - uInt *, /* maximum lookup bits (returns actual) */ - inflate_huft *, /* space for trees */ - uInt *, /* hufts used in space */ - uInt * ) ); /* space for values */ +static int huft_build OF(( + uInt *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uInt *, /* list of base values for non-simple codes */ + const uInt *, /* list of extra bits for non-simple codes */ + inflate_huft **, /* result: starting table */ + uInt *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uInt * )); /* space for values */ /* Tables for deflate from PKZIP's appnote.txt. */ static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -}; -/* see note #13 above about 258 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 -}; /* 112==invalid */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 -}; + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; static const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13 -}; + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; /* Huffman code decoding is performed using a multi-level table lookup. @@ -3396,7 +3289,7 @@ static const uInt cpdext[30] = { /* Extra bits for distance codes */ /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ #define BMAX 15 /* maximum bit length of any code */ -static int huft_build( uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v ){ +static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v) //uInt *b; /* code lengths in bits (all assumed <= BMAX) */ //uInt n; /* number of codes (assumed <= 288) */ //uInt s; /* number of simple-valued codes (0..s-1) */ @@ -3412,229 +3305,221 @@ static int huft_build( uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, in if the given code set is incomplete (the tables are still built in this case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ - uInt a; /* counter for codes of length k */ - uInt c[BMAX + 1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ - register uInt *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX + 1]; /* bit offsets, then code stack */ - uInt *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uInt *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uInt *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ - /* Generate counts for each bit length */ - p = c; + /* Generate counts for each bit length */ + p = c; #define C0 *p++ = 0; #define C2 C0 C0 C0 C0 #define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while ( --i ); - if ( c[0] == n ) { /* null input--all zero length codes */ - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for ( j = 1; j <= BMAX; j++ ) - if ( c[j] ) { - break; - } - k = j; /* minimum code length */ - if ( (uInt)l < j ) { - l = j; - } - for ( i = BMAX; i; i-- ) - if ( c[i] ) { - break; - } - g = i; /* maximum code length */ - if ( (uInt)l > i ) { - l = i; - } - *m = l; + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; - /* Adjust last length count to fill out codes, if needed */ - for ( y = 1 << j; j < i; j++, y <<= 1 ) - if ( ( y -= c[j] ) < 0 ) { - return Z_DATA_ERROR; - } - if ( ( y -= c[i] ) < 0 ) { - return Z_DATA_ERROR; - } - c[i] += y; + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while ( --i ) { /* note that i == g from above */ - *xp++ = ( j += *p++ ); - } + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ( ( j = *p++ ) != 0 ) { - v[x[j]++] = i; - } - } while ( ++i < n ); - n = x[g]; /* set n to length of v */ + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++ ) - { - a = c[k]; - while ( a-- ) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while ( k > w + l ) - { - h++; - w += l; /* previous table always l bits */ + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ( ( f = 1 << ( j = k - w ) ) > a + 1 ) { /* try a k-w bit table */ - /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if ( j < z ) { - while ( ++j < z ) /* try smaller tables up to z bits */ - { - if ( ( f <<= 1 ) <= *++xp ) { - break; /* enough codes to use up j bits */ - } - f -= *xp; /* else deduct codes from patterns */ - } - } - } - z = 1 << j; /* table entries for j-bit table */ + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ - /* allocate new table */ - if ( *hn + z > MANY ) { /* (note: doesn't matter for fixed) */ - return Z_MEM_ERROR; /* not enough memory */ - } - u[h] = q = hp + *hn; - *hn += z; + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_MEM_ERROR; /* not enough memory */ + u[h] = q = hp + *hn; + *hn += z; - /* connect to last table, if there is one */ - if ( h ) { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - j = i >> ( w - l ); - r.base = (uInt)( q - u[h - 1] - j ); /* offset to this table */ - u[h - 1][j] = r; /* connect to last table */ - } - else{ - *t = q; /* first table is returned result */ - } - } + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } - /* set up table entry in r */ - r.bits = (Byte)( k - w ); - if ( p >= v + n ) { - r.exop = 128 + 64; /* out of values--invalid code */ - } - else if ( *p < s ) { - r.exop = (Byte)( *p < 256 ? 0 : 32 + 64 ); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)( e[*p - s] + 16 + 64 ); /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } - /* fill code-like entries with r */ - f = 1 << ( k - w ); - for ( j = i >> w; j < z; j += f ) - q[j] = r; + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; - /* backwards increment the k-bit code i */ - for ( j = 1 << ( k - 1 ); i &j; j >>= 1 ) - i ^= j; - i ^= j; + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; - /* backup over finished tables */ - mask = ( 1 << w ) - 1; /* needed on HP, cc -O bug */ - while ( ( i & mask ) != x[h] ) - { - h--; /* don't need to update q */ - w -= l; - mask = ( 1 << w ) - 1; - } - } - } + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } #ifndef __APPLE__ -int inflate_trees_bits( uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z ){ +int inflate_trees_bits(uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z) //uInt *c; /* 19 code lengths */ //uInt *bb; /* bits tree desired/actual depth */ //inflate_huft * *tb; /* bits tree result */ //inflate_huft *hp; /* space for trees */ //z_streamp z; /* for messages */ - int r; - uInt hn = 0; /* hufts used in space */ - uInt *v; /* work area for huft_build */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uInt *v; /* work area for huft_build */ - if ( ( v = (uInt*)ZALLOC( z, 19, sizeof( uInt ) ) ) == Z_NULL ) { - return Z_MEM_ERROR; - } - r = huft_build( c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, - tb, bb, hp, &hn, v ); - if ( r == Z_DATA_ERROR ) { - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - } - else if ( r == Z_BUF_ERROR || *bb == 0 ) { - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - ZFREE( z, v ); - return r; + if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; } #endif #ifndef __APPLE__ -int inflate_trees_dynamic( uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z ){ +int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z) //uInt nl; /* number of literal/length codes */ //uInt nd; /* number of distance codes */ //uInt *c; /* that many (total) code lengths */ @@ -3644,55 +3529,57 @@ int inflate_trees_dynamic( uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflat //inflate_huft * *td; /* distance tree result */ //inflate_huft *hp; /* space for trees */ //z_streamp z; /* for messages */ - int r; - uInt hn = 0; /* hufts used in space */ - uInt *v; /* work area for huft_build */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uInt *v; /* work area for huft_build */ - /* allocate work area */ - if ( ( v = (uInt*)ZALLOC( z, 288, sizeof( uInt ) ) ) == Z_NULL ) { - return Z_MEM_ERROR; - } + /* allocate work area */ + if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; - /* build literal/length tree */ - r = huft_build( c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v ); - if ( r != Z_OK || *bl == 0 ) { - if ( r == Z_DATA_ERROR ) { - z->msg = (char*)"oversubscribed literal/length tree"; - } - else if ( r != Z_MEM_ERROR ) { - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - ZFREE( z, v ); - return r; - } + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } - /* build distance tree */ - r = huft_build( c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v ); - if ( r != Z_OK || ( *bd == 0 && nl > 257 ) ) { - if ( r == Z_DATA_ERROR ) { - z->msg = (char*)"oversubscribed distance tree"; - } - else if ( r == Z_BUF_ERROR ) { + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { #ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } + r = Z_OK; + } #else - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if ( r != Z_MEM_ERROR ) { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - ZFREE( z, v ); - return r; + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; #endif - } + } - /* done */ - ZFREE( z, v ); - return Z_OK; + /* done */ + ZFREE(z, v); + return Z_OK; } #endif @@ -3708,158 +3595,159 @@ int inflate_trees_dynamic( uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflat static uInt fixed_bl = 9; static uInt fixed_bd = 5; static inflate_huft fixed_tl[] = { - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} -}; + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; static inflate_huft fixed_td[] = { - {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, - {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, - {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, - {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, - {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, - {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, - {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, - {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} -}; + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; #ifndef __APPLE__ -int inflate_trees_fixed( uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z ){ +int inflate_trees_fixed(uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z) //uInt *bl; /* literal desired/actual bit depth */ //uInt *bd; /* distance desired/actual bit depth */ //inflate_huft * *tl; /* literal/length tree result */ //inflate_huft * *td; /* distance tree result */ //z_streamp z; /* for memory allocation */ - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; +{ + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; } #endif @@ -3868,8 +3756,8 @@ int inflate_trees_fixed( uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS( j ) {while ( k < ( j ) ) {b |= ( (uLong)NEXTBYTE ) << k; k += 8; }} -#define UNGRAB {c = z->avail_in - n; c = ( k >> 3 ) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; } +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} /* Called with number of bytes left to write in window at least 258 (the maximum string length) and number of input bytes available @@ -3877,140 +3765,149 @@ int inflate_trees_fixed( uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * distance pair plus four bytes for overloading the bit buffer. */ #ifndef __APPLE__ -int inflate_fast( uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z ){ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Byte *r; /* copy source pointer */ +int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z) +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Byte *r; /* copy source pointer */ - /* load input, output, bit values */ - LOAD + /* load input, output, bit values */ + LOAD - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS( 20 ) /* max bits for literal/length code */ - if ( ( e = ( t = tl + ( (uInt)b & ml ) )->exop ) == 0 ) { - DUMPBITS( t->bits ) - Tracevv( ( t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base ) ); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS( t->bits ) - if ( e & 16 ) { - /* get extra bits for length */ - e &= 15; - c = t->base + ( (uInt)b & inflate_mask[e] ); - DUMPBITS( e ) - Tracevv( ( "inflate: * length %u\n", c ) ); + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv(("inflate: * length %u\n", c)); - /* decode distance base of block to copy */ - GRABBITS( 15 ); /* max bits for distance code */ - e = ( t = td + ( (uInt)b & md ) )->exop; - do { - DUMPBITS( t->bits ) - if ( e & 16 ) { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS( e ) /* get extra bits (up to 13) */ - d = t->base + ( (uInt)b & inflate_mask[e] ); - DUMPBITS( e ) - Tracevv( ( "inflate: * distance %u\n", d ) ); + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv(("inflate: * distance %u\n", d)); - /* do the copy */ - m -= c; - if ( (uInt)( q - s->window ) >= d ) { /* offset before dest */ - /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)( q - s->window ); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if ( c > e ) { /* if source crosses, */ - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while ( --e ); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while ( --c ); - break; - } - else if ( ( e & 64 ) == 0 ) { - t += t->base; - e = ( t += ( (uInt)b & inflate_mask[e] ) )->exop; - } - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while ( 1 ); - break; - } - if ( ( e & 64 ) == 0 ) { - t += t->base; - if ( ( e = ( t += ( (uInt)b & inflate_mask[e] ) )->exop ) == 0 ) { - DUMPBITS( t->bits ) - Tracevv( ( t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base ) ); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if ( e & 32 ) { - Tracevv( ( "inflate: * end of block\n" ) ); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while ( 1 ); - } while ( m >= 258 && n >= 10 ); + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (uInt)(q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv(("inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; } #endif /* infcodes.c -- process literals and length/distance pairs * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ @@ -4018,235 +3915,244 @@ int inflate_fast( uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_ #define bits word.what.Bits typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE -} /* x: got error */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ inflate_codes_mode; /* inflate codes private state */ struct inflate_codes_state { - /* mode */ - inflate_codes_mode mode; /* current inflate_codes mode */ + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ }; #ifndef __APPLE__ -inflate_codes_statef *inflate_codes_new( uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z ){ - inflate_codes_statef *c; +inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z) +{ + inflate_codes_statef *c; - if ( ( c = (inflate_codes_statef *) - ZALLOC( z,1,sizeof( struct inflate_codes_state ) ) ) != Z_NULL ) { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev( ( "inflate: codes new\n" ) ); - } - return c; + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev(("inflate: codes new\n")); + } + return c; } #endif #ifndef __APPLE__ -int inflate_codes( inflate_blocks_statef *s, z_streamp z, int r ){ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Byte *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ +int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Byte *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD - /* process input and output based on current state */ - while ( 1 ) switch ( c->mode ) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ #ifndef SLOW - if ( m >= 258 && n >= 10 ) { - UPDATE - r = inflate_fast( c->lbits, c->dbits, c->ltree, c->dtree, s, z ); - LOAD - if ( r != Z_OK ) { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } #endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS( j ) - t = c->sub.code.tree + ( (uInt)b & inflate_mask[j] ); - DUMPBITS( t->bits ) - e = (uInt)( t->exop ); - if ( e == 0 ) { /* literal */ - c->sub.lit = t->base; - Tracevv( ( t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base ) ); - c->mode = LIT; - break; - } - if ( e & 16 ) { /* length */ - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ( ( e & 64 ) == 0 ) { /* next table */ - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - if ( e & 32 ) { /* end of block */ - Tracevv( ( "inflate: end of block\n" ) ); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS( j ) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS( j ) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv( ( "inflate: length %u\n", c->len ) ); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS( j ) - t = c->sub.code.tree + ( (uInt)b & inflate_mask[j] ); - DUMPBITS( t->bits ) - e = (uInt)( t->exop ); - if ( e & 16 ) { /* distance */ - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ( ( e & 64 ) == 0 ) { /* next table */ - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS( j ) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS( j ) - Tracevv( ( "inflate: distance %u\n", c->sub.copy.dist ) ); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv(("inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv(("inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv(("inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ #ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)( q - s->window ) < c->sub.copy.dist ? - s->end - ( c->sub.copy.dist - ( q - s->window ) ) : - q - c->sub.copy.dist; + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; #else - f = q - c->sub.copy.dist; - if ( (uInt)( q - s->window ) < c->sub.copy.dist ) { - f = s->end - ( c->sub.copy.dist - (uInt)( q - s->window ) ); - } + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); #endif - while ( c->len ) - { - NEEDOUT - OUTBYTE( *f++ ) - if ( f == s->end ) { - f = s->window; - } - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE( c->sub.lit ) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - if ( k > 7 ) { /* return unused byte, if any */ - Assert( k < 16, "inflate_codes grabbed too many bytes" ) - k -= 8; - n++; - p--; /* can always return one */ - } - FLUSH - if ( s->read != s->write ) { - LEAVE - c->mode = END; - } - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } #ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } #endif #ifndef __APPLE__ -void inflate_codes_free( inflate_codes_statef *c, z_streamp z ){ - ZFREE( z, c ); - Tracev( ( "inflate: codes free\n" ) ); +void inflate_codes_free(inflate_codes_statef *c, z_streamp z) +{ + ZFREE(z, c); + Tracev(("inflate: codes free\n")); } #endif /* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ #define BASE 65521L /* largest prime smaller than 65536 */ @@ -4258,48 +4164,45 @@ void inflate_codes_free( inflate_codes_statef *c, z_streamp z ){ #undef DO4 #undef DO8 -#define DO1( buf,i ) {s1 += buf[i]; s2 += s1; } -#define DO2( buf,i ) DO1( buf,i ); DO1( buf,i + 1 ); -#define DO4( buf,i ) DO2( buf,i ); DO2( buf,i + 2 ); -#define DO8( buf,i ) DO4( buf,i ); DO4( buf,i + 4 ); -#define DO16( buf ) DO8( buf,0 ); DO8( buf,8 ); +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); /* ========================================================================= */ #ifndef __APPLE__ -uLong adler32( uLong adler, const Byte *buf, uInt len ){ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = ( adler >> 16 ) & 0xffff; - int k; +uLong adler32(uLong adler, const Byte *buf, uInt len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; - if ( buf == Z_NULL ) { - return 1L; - } + if (buf == Z_NULL) return 1L; - while ( len > 0 ) { - k = len < NMAX ? len : NMAX; - len -= k; - while ( k >= 16 ) { - DO16( buf ); - buf += 16; - k -= 16; - } - if ( k != 0 ) { - do { - s1 += *buf++; - s2 += s1; - } while ( --k ); - } - s1 %= BASE; - s2 %= BASE; - } - return ( s2 << 16 ) | s1; + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; } #endif /* infblock.h -- header to use infblock.c * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is @@ -4307,365 +4210,364 @@ uLong adler32( uLong adler, const Byte *buf, uInt len ){ subject to change. Applications should only use zlib.h. */ -extern inflate_blocks_statef * inflate_blocks_new OF( ( - z_streamp z, - check_func c, /* check function */ - uInt w ) ); /* window size */ +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ -extern int inflate_blocks OF( ( - inflate_blocks_statef *, - z_streamp, - int ) ); /* initial return code */ +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ -extern void inflate_blocks_reset OF( ( - inflate_blocks_statef *, - z_streamp, - uLong * ) ); /* check value on output */ +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLong *)); /* check value on output */ -extern int inflate_blocks_free OF( ( - inflate_blocks_statef *, - z_streamp ) ); +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); -extern void inflate_set_dictionary OF( ( - inflate_blocks_statef * s, - const Byte * d, /* dictionary */ - uInt n ) ); /* dictionary length */ +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Byte *d, /* dictionary */ + uInt n)); /* dictionary length */ -extern int inflate_blocks_sync_point OF( ( - inflate_blocks_statef * s ) ); +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); typedef enum { - imMETHOD, /* waiting for method byte */ - imFLAG, /* waiting for flag byte */ - imDICT4, /* four dictionary check bytes to go */ - imDICT3, /* three dictionary check bytes to go */ - imDICT2, /* two dictionary check bytes to go */ - imDICT1, /* one dictionary check byte to go */ - imDICT0, /* waiting for inflateSetDictionary */ - imBLOCKS, /* decompressing blocks */ - imCHECK4, /* four check bytes to go */ - imCHECK3, /* three check bytes to go */ - imCHECK2, /* two check bytes to go */ - imCHECK1, /* one check byte to go */ - imDONE, /* finished check, done */ - imBAD -} /* got an error--stay here */ + imMETHOD, /* waiting for method byte */ + imFLAG, /* waiting for flag byte */ + imDICT4, /* four dictionary check bytes to go */ + imDICT3, /* three dictionary check bytes to go */ + imDICT2, /* two dictionary check bytes to go */ + imDICT1, /* one dictionary check byte to go */ + imDICT0, /* waiting for inflateSetDictionary */ + imBLOCKS, /* decompressing blocks */ + imCHECK4, /* four check bytes to go */ + imCHECK3, /* three check bytes to go */ + imCHECK2, /* two check bytes to go */ + imCHECK1, /* one check byte to go */ + imDONE, /* finished check, done */ + imBAD} /* got an error--stay here */ inflate_mode; /* inflate private state */ struct internal_state { - /* mode */ - inflate_mode mode; /* current inflate mode */ + /* mode */ + inflate_mode mode; /* current inflate mode */ - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ }; #ifndef __APPLE__ -int inflateReset( z_streamp z ){ - if ( z == Z_NULL || z->state == Z_NULL ) { - return Z_STREAM_ERROR; - } - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; - inflate_blocks_reset( z->state->blocks, z, Z_NULL ); - Tracev( ( "inflate: reset\n" ) ); - return Z_OK; +int inflateReset(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev(("inflate: reset\n")); + return Z_OK; } #endif #ifndef __APPLE__ -int inflateEnd( z_streamp z ){ - if ( z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL ) { - return Z_STREAM_ERROR; - } - if ( z->state->blocks != Z_NULL ) { - inflate_blocks_free( z->state->blocks, z ); - } - ZFREE( z, z->state ); - z->state = Z_NULL; - Tracev( ( "inflate: end\n" ) ); - return Z_OK; +int inflateEnd(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev(("inflate: end\n")); + return Z_OK; } #endif #ifndef __APPLE__ -int inflateInit2_( z_streamp z, int w, const char *version, int stream_size ){ - if ( version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof( z_stream ) ) { - return Z_VERSION_ERROR; - } +int inflateInit2_(z_streamp z, int w, const char *version, int stream_size) +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; - /* initialize state */ - if ( z == Z_NULL ) { - return Z_STREAM_ERROR; - } - z->msg = Z_NULL; - if ( z->zalloc == Z_NULL ) { - z->zalloc = ( void *( * )( void *, unsigned, unsigned ) )zcalloc; - z->opaque = (voidp)0; - } - if ( z->zfree == Z_NULL ) { - z->zfree = ( void ( * )( void *, void * ) )zcfree; - } - if ( ( z->state = (struct internal_state *) - ZALLOC( z,1,sizeof( struct internal_state ) ) ) == Z_NULL ) { - return Z_MEM_ERROR; - } - z->state->blocks = Z_NULL; + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = (void *(*)(void *, unsigned, unsigned))zcalloc; + z->opaque = (voidp)0; + } + if (z->zfree == Z_NULL) z->zfree = (void (*)(void *, void *))zcfree; + if ((z->state = (struct internal_state *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if ( w < 0 ) { - w = -w; - z->state->nowrap = 1; - } + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } - /* set window size */ - if ( w < 8 || w > 15 ) { - inflateEnd( z ); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; - /* create inflate_blocks state */ - if ( ( z->state->blocks = - inflate_blocks_new( z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w ) ) - == Z_NULL ) { - inflateEnd( z ); - return Z_MEM_ERROR; - } - Tracev( ( "inflate: allocated\n" ) ); + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev(("inflate: allocated\n")); - /* reset state */ - inflateReset( z ); - return Z_OK; + /* reset state */ + inflateReset(z); + return Z_OK; } #endif #ifndef __APPLE__ -int inflateInit_( z_streamp z, const char *version, int stream_size ){ - return inflateInit2_( z, DEF_WBITS, version, stream_size ); +int inflateInit_(z_streamp z, const char *version, int stream_size) +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); } #endif -#define iNEEDBYTE {if ( z->avail_in == 0 ) {return r; } r = f; } -#define iNEXTBYTE ( z->avail_in--,z->total_in++,*z->next_in++ ) +#define iNEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define iNEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) #ifndef __APPLE__ -int inflate( z_streamp z, int f ){ - int r; - uInt b; +int inflate(z_streamp z, int f) +{ + int r; + uInt b; - if ( z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL ) { - return Z_STREAM_ERROR; - } - f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; - r = Z_BUF_ERROR; - while ( 1 ) switch ( z->state->mode ) - { - case imMETHOD: - iNEEDBYTE - if ( ( ( z->state->sub.method = iNEXTBYTE ) & 0xf ) != Z_DEFLATED ) { - z->state->mode = imBAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ( ( z->state->sub.method >> 4 ) + 8 > z->state->wbits ) { - z->state->mode = imBAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = imFLAG; - case imFLAG: - iNEEDBYTE - b = iNEXTBYTE; - if ( ( ( z->state->sub.method << 8 ) + b ) % 31 ) { - z->state->mode = imBAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Tracev( ( "inflate: zlib header ok\n" ) ); - if ( !( b & PRESET_DICT ) ) { - z->state->mode = imBLOCKS; - break; - } - z->state->mode = imDICT4; - case imDICT4: - iNEEDBYTE - z->state->sub.check.need = (uLong)iNEXTBYTE << 24; - z->state->mode = imDICT3; - case imDICT3: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 16; - z->state->mode = imDICT2; - case imDICT2: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 8; - z->state->mode = imDICT1; - case imDICT1: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = imDICT0; - return Z_NEED_DICT; - case imDICT0: - z->state->mode = imBAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case imBLOCKS: - r = inflate_blocks( z->state->blocks, z, r ); - if ( r == Z_DATA_ERROR ) { - z->state->mode = imBAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if ( r == Z_OK ) { - r = f; - } - if ( r != Z_STREAM_END ) { - return r; - } - r = f; - inflate_blocks_reset( z->state->blocks, z, &z->state->sub.check.was ); - if ( z->state->nowrap ) { - z->state->mode = imDONE; - break; - } - z->state->mode = imCHECK4; - case imCHECK4: - iNEEDBYTE - z->state->sub.check.need = (uLong)iNEXTBYTE << 24; - z->state->mode = imCHECK3; - case imCHECK3: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 16; - z->state->mode = imCHECK2; - case imCHECK2: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 8; - z->state->mode = imCHECK1; - case imCHECK1: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE; + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case imMETHOD: + iNEEDBYTE + if (((z->state->sub.method = iNEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = imBAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = imBAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = imFLAG; + case imFLAG: + iNEEDBYTE + b = iNEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = imBAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev(("inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = imBLOCKS; + break; + } + z->state->mode = imDICT4; + case imDICT4: + iNEEDBYTE + z->state->sub.check.need = (uLong)iNEXTBYTE << 24; + z->state->mode = imDICT3; + case imDICT3: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 16; + z->state->mode = imDICT2; + case imDICT2: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 8; + z->state->mode = imDICT1; + case imDICT1: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = imDICT0; + return Z_NEED_DICT; + case imDICT0: + z->state->mode = imBAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case imBLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = imBAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = imDONE; + break; + } + z->state->mode = imCHECK4; + case imCHECK4: + iNEEDBYTE + z->state->sub.check.need = (uLong)iNEXTBYTE << 24; + z->state->mode = imCHECK3; + case imCHECK3: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 16; + z->state->mode = imCHECK2; + case imCHECK2: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE << 8; + z->state->mode = imCHECK1; + case imCHECK1: + iNEEDBYTE + z->state->sub.check.need += (uLong)iNEXTBYTE; - if ( z->state->sub.check.was != z->state->sub.check.need ) { - z->state->mode = imBAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Tracev( ( "inflate: zlib check ok\n" ) ); - z->state->mode = imDONE; - case imDONE: - return Z_STREAM_END; - case imBAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = imBAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev(("inflate: zlib check ok\n")); + z->state->mode = imDONE; + case imDONE: + return Z_STREAM_END; + case imBAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } #ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } #endif #ifndef __APPLE__ -int inflateSetDictionary( z_streamp z, const Byte *dictionary, uInt dictLength ){ - uInt length = dictLength; +int inflateSetDictionary(z_streamp z, const Byte *dictionary, uInt dictLength) +{ + uInt length = dictLength; - if ( z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0 ) { - return Z_STREAM_ERROR; - } + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0) + return Z_STREAM_ERROR; - if ( adler32( 1L, dictionary, dictLength ) != z->adler ) { - return Z_DATA_ERROR; - } - z->adler = 1L; + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; - if ( length >= ( (uInt)1 << z->state->wbits ) ) { - length = ( 1 << z->state->wbits ) - 1; - dictionary += dictLength - length; - } - inflate_set_dictionary( z->state->blocks, dictionary, length ); - z->state->mode = imBLOCKS; - return Z_OK; + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = imBLOCKS; + return Z_OK; } #endif #ifndef __APPLE__ -int inflateSync( z_streamp z ){ - uInt n; /* number of bytes to look at */ - Byte *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ +int inflateSync(z_streamp z) +{ + uInt n; /* number of bytes to look at */ + Byte *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ - /* set up */ - if ( z == Z_NULL || z->state == Z_NULL ) { - return Z_STREAM_ERROR; - } - if ( z->state->mode != imBAD ) { - z->state->mode = imBAD; - z->state->sub.marker = 0; - } - if ( ( n = z->avail_in ) == 0 ) { - return Z_BUF_ERROR; - } - p = z->next_in; - m = z->state->sub.marker; + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != imBAD) + { + z->state->mode = imBAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; - /* search */ - while ( n && m < 4 ) - { - static const Byte mark[4] = {0, 0, 0xff, 0xff}; - if ( *p == mark[m] ) { - m++; - } - else if ( *p ) { - m = 0; - } - else{ - m = 4 - m; - } - p++, n--; - } + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; - /* return no joy or set up to restart on a new block */ - if ( m != 4 ) { - return Z_DATA_ERROR; - } - r = z->total_in; w = z->total_out; - inflateReset( z ); - z->total_in = r; z->total_out = w; - z->state->mode = imBLOCKS; - return Z_OK; + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = imBLOCKS; + return Z_OK; } #endif @@ -4677,26 +4579,24 @@ int inflateSync( z_streamp z ){ * waiting for these length bytes. */ #ifndef __APPLE__ -int inflateSyncPoint( z_streamp z ){ - if ( z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL ) { - return Z_STREAM_ERROR; - } - return inflate_blocks_sync_point( z->state->blocks ); +int inflateSyncPoint(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); } #endif #ifndef __APPLE__ -voidp zcalloc( voidp opaque, unsigned items, unsigned size ){ - if ( opaque ) { - items += size - size; /* make compiler happy */ - } - return (voidp)safe_malloc( items * size ); +voidp zcalloc (voidp opaque, unsigned items, unsigned size) +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidp)safe_malloc(items*size); } -void zcfree( voidp opaque, voidp ptr ){ - free( ptr ); - if ( opaque ) { - return; /* make compiler happy */ - } +void zcfree (voidp opaque, voidp ptr) +{ + free(ptr); + if (opaque) return; /* make compiler happy */ } #endif From 943424faa1514f24b63524161d299734a8c3f8bd Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sat, 14 Apr 2012 17:31:10 -0500 Subject: [PATCH 04/16] fix q3map2 --- tools/quake3/common/cmdlib.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/quake3/common/cmdlib.c b/tools/quake3/common/cmdlib.c index 35f4d75b..3c01cc99 100644 --- a/tools/quake3/common/cmdlib.c +++ b/tools/quake3/common/cmdlib.c @@ -244,9 +244,6 @@ char *ExpandArg( const char *path ){ char *ExpandPath( const char *path ){ static char full[1024]; - if ( !qdir[0] ) { - Error( "ExpandPath called without qdir set" ); - } if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { strcpy( full, path ); return full; @@ -257,9 +254,6 @@ char *ExpandPath( const char *path ){ char *ExpandGamePath( const char *path ){ static char full[1024]; - if ( !qdir[0] ) { - Error( "ExpandGamePath called without qdir set" ); - } if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { strcpy( full, path ); return full; From 6873f53847c9b4946a781f86936a0a35a637f711 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 15 Apr 2012 11:24:08 -0500 Subject: [PATCH 05/16] only Q3 and UrT pack for now. will need maintainers on the others to re-add them --- config.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/config.py b/config.py index a1dad7c4..f872a25e 100644 --- a/config.py +++ b/config.py @@ -33,7 +33,7 @@ class Config: # platforms for which to assemble a setup self.setup_platforms = [ 'local', 'x86', 'x64', 'win32' ] # paks to assemble in the setup - self.setup_packs = [ 'Q3Pack', 'UrTPack', 'UFOAIPack', 'Q2WPack', 'ReactionPack' ] + self.setup_packs = [ 'Q3Pack', 'UrTPack', ] # 'UFOAIPack', 'Q2WPack', 'ReactionPack' ] def __repr__( self ): return 'config: target=%s config=%s' % ( self.target_selected, self.config_selected ) @@ -261,9 +261,8 @@ class Config: def FetchGamePaks( self, path ): for pak in self.setup_packs: - if ( pak == 'Q3Pack' or pak == 'UrTPack' or pak == 'UFOAIPack' or pak == 'Q2WPack' or pak == 'ReactionPack' ): - svnurl = 'svn://svn.icculus.org/gtkradiant-gamepacks/%s/trunk' % pak - self.CheckoutOrUpdate( svnurl, os.path.join( path, 'installs', pak ) ) + svnurl = 'svn://svn.icculus.org/gtkradiant-gamepacks/%s/trunk' % pak + self.CheckoutOrUpdate( svnurl, os.path.join( path, 'installs', pak ) ) def CopyTree( self, src, dst): for root, dirs, files in os.walk( src ): From c40e0b3e57052736bd3778c93db0c3789cd00fb2 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 15 Apr 2012 11:24:38 -0500 Subject: [PATCH 06/16] unused --- tools/quake3/common/cmdlib.c | 24 ------------------------ tools/quake3/common/cmdlib.h | 2 -- 2 files changed, 26 deletions(-) diff --git a/tools/quake3/common/cmdlib.c b/tools/quake3/common/cmdlib.c index 3c01cc99..94c260d3 100644 --- a/tools/quake3/common/cmdlib.c +++ b/tools/quake3/common/cmdlib.c @@ -252,30 +252,6 @@ char *ExpandPath( const char *path ){ return full; } -char *ExpandGamePath( const char *path ){ - static char full[1024]; - if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { - strcpy( full, path ); - return full; - } - sprintf( full, "%s%s", gamedir, path ); - return full; -} - -char *ExpandPathAndArchive( const char *path ){ - char *expanded; - char archivename[1024]; - - expanded = ExpandPath( path ); - - if ( archive ) { - sprintf( archivename, "%s/%s", archivedir, path ); - QCopyFile( expanded, archivename ); - } - return expanded; -} - - char *copystring( const char *s ){ char *b; b = safe_malloc( strlen( s ) + 1 ); diff --git a/tools/quake3/common/cmdlib.h b/tools/quake3/common/cmdlib.h index 3fb98feb..e8d6326f 100644 --- a/tools/quake3/common/cmdlib.h +++ b/tools/quake3/common/cmdlib.h @@ -88,8 +88,6 @@ extern char *moddirparam; void SetQdirFromPath( const char *path ); char *ExpandArg( const char *path ); // from cmd line char *ExpandPath( const char *path ); // from scripts -char *ExpandGamePath( const char *path ); -char *ExpandPathAndArchive( const char *path ); void ExpandWildcards( int *argc, char ***argv ); From a2a93d30dfcce802e911c14ed67c48d63ebed3e0 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 22 Apr 2012 19:43:26 -0500 Subject: [PATCH 07/16] fix bobtoolz patch caulk crash --- radiant/pluginmanager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/radiant/pluginmanager.cpp b/radiant/pluginmanager.cpp index bd5f7135..d8eff122 100644 --- a/radiant/pluginmanager.cpp +++ b/radiant/pluginmanager.cpp @@ -2029,6 +2029,7 @@ bool CSynapseClientRadiant::RequestAPI( APIDescriptor_t *pAPI ){ pTable->m_pfnDeletePatch = &QERApp_DeletePatch; pTable->m_pfnCreatePatchHandle = &QERApp_CreatePatchHandle; pTable->m_pfnCommitPatchHandleToMap = &QERApp_CommitPatchHandleToMap; + pTable->m_pfnCommitPatchHandleToEntity = &QERApp_CommitPatchHandleToEntity; pTable->m_pfnLoadImage = &QERApp_LoadImage; pTable->m_pfnMessageBox = >k_MessageBox; pTable->m_pfnFileDialog = &file_dialog; From 5ed7a304a7fe83c1812d67dd0771501e01f5c950 Mon Sep 17 00:00:00 2001 From: Christian Ratzenhofer Date: Fri, 4 May 2012 00:18:30 +0200 Subject: [PATCH 08/16] Properly name game configuration files, fixes #43 and other issues related to stringcompares against config filename --- radiant/preferences.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 430c751f..7759ed5f 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -3411,8 +3411,40 @@ void CGameInstall::Run() { if(CheckFile(gameFilePath) != PATH_DIRECTORY) { radCreateDirectory(gameFilePath); } - gameFilePath += m_strName.GetBuffer(); - gameFilePath += ".game"; + + switch ( m_availGame[ m_nComboSelect ] ) { + case GAME_Q2: + gameFilePath += "q2.game"; + break; + case GAME_Q3: + gameFilePath += "q3.game"; + break; + case GAME_URT: + gameFilePath += "urt.game"; + break; + case GAME_UFOAI: + gameFilePath += "ufoai.game"; + break; + case GAME_Q2W: + gameFilePath += "q2w.game"; + break; + case GAME_WARSOW: + gameFilePath += "warsow.game"; + break; + case GAME_NEXUIZ: + gameFilePath += "nexuiz.game"; + break; + case GAME_TREMULOUS: + gameFilePath += "tremulous.game"; + break; + case GAME_JA: + gameFilePath += "ja.game"; + break; + case GAME_REACTION: + gameFilePath += "reaction.game"; + break; + } + Sys_Printf( "game file: %s\n", gameFilePath.GetBuffer() ); FILE * fg = fopen( gameFilePath.GetBuffer(), "w" ); From 22de3606a6b30e92ec1c61c50a5e28571fa4dad0 Mon Sep 17 00:00:00 2001 From: Willi Schinmeyer Date: Fri, 4 May 2012 10:02:31 +0200 Subject: [PATCH 09/16] If the first argument ends in .map, try to load it as a map (instead of as a project) --- radiant/main.cpp | 6 +++++- radiant/mainframe.cpp | 9 +++++++-- radiant/mainframe.h | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/radiant/main.cpp b/radiant/main.cpp index 2fa52214..ede1426f 100644 --- a/radiant/main.cpp +++ b/radiant/main.cpp @@ -894,7 +894,11 @@ int main( int argc, char* argv[] ) { g_pParentWnd = new MainFrame(); - if ( g_PrefsDlg.m_bLoadLastMap && g_PrefsDlg.m_strLastMap.GetLength() > 0 ) { + // If the first parameter is a .map, load that. + if( g_argc > 1 && IsMap( g_argv[1] ) ){ + Map_LoadFile( g_argv[1] ); + } + else if ( g_PrefsDlg.m_bLoadLastMap && g_PrefsDlg.m_strLastMap.GetLength() > 0 ) { Map_LoadFile( g_PrefsDlg.m_strLastMap.GetBuffer() ); } else { diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 9368292f..6d24c98b 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -3619,9 +3619,14 @@ void MainFrame::ShowMenuItemKeyBindings( GtkWidget* window ){ } } +// Checks whether a given filename ends in .map +const bool IsMap(const char* filename){ + return strlen(filename) >= 4 && strcmp(filename + strlen(filename) - 4, ".map") == 0; +} + void MainFrame::CreateQEChildren(){ - // load the project file - if ( g_argc > 1 ) { + // load the project file, if it is a project project file. (Or at least no .map) + if ( g_argc > 1 && !IsMap( g_argv[1] ) ) { Sys_Printf( "loading project file from the command line: %s\n", g_argv[1] ); if ( !QE_LoadProject( g_argv[1] ) ) { Error( "Unable to load project file %s\n", g_argv[1] ); diff --git a/radiant/mainframe.h b/radiant/mainframe.h index e72adc4c..3caf5840 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -908,4 +908,7 @@ int gdk_offset_y; // some C API to the mainframe functions void WINAPI QERApp_Sleep(); +// Checks whether a given filename ends in .map +const bool IsMap(const char* filename); + #endif // _MAINFRAME_H_ From ead68d88845bd55d0f67973a82fcb9c0717ad6f9 Mon Sep 17 00:00:00 2001 From: Willi Schinmeyer Date: Fri, 4 May 2012 10:07:28 +0200 Subject: [PATCH 10/16] Fixed spelling in a comment --- radiant/mainframe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 6d24c98b..70a5a1f8 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -3625,7 +3625,7 @@ const bool IsMap(const char* filename){ } void MainFrame::CreateQEChildren(){ - // load the project file, if it is a project project file. (Or at least no .map) + // load the project file, if it is a project file. (Or at least no .map) if ( g_argc > 1 && !IsMap( g_argv[1] ) ) { Sys_Printf( "loading project file from the command line: %s\n", g_argv[1] ); if ( !QE_LoadProject( g_argv[1] ) ) { From 069d2350ebfd80e3bf5877396f973d848aaf898c Mon Sep 17 00:00:00 2001 From: Willi Schinmeyer Date: Fri, 4 May 2012 10:32:48 +0200 Subject: [PATCH 11/16] Fixed transparency (qer_trans) not working on models --- plugins/model/cpicosurface.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/model/cpicosurface.cpp b/plugins/model/cpicosurface.cpp index da88eb58..470623fa 100644 --- a/plugins/model/cpicosurface.cpp +++ b/plugins/model/cpicosurface.cpp @@ -48,12 +48,18 @@ void CPicoSurface::Draw( int state, IShader *pShader, int rflags ){ if ( !( rflags & ( DRAW_RF_SEL_OUTLINE | DRAW_RF_SEL_FILL | DRAW_RF_XY ) ) ) { if ( state & DRAW_GL_TEXTURE_2D ) { + bool bTrans = ( pShader->getFlags() & QER_TRANS ) == QER_TRANS; + bool bDrawBlend = ( state & DRAW_GL_BLEND ) == DRAW_GL_BLEND; + //only draw transparent stuff when in transparent stuff pass and vice versa + if(bTrans != bDrawBlend) { + return; + } g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, pShader->getTexture()->texture_number ); if ( ( rflags & DRAW_RF_CAM ) && ( pShader->getFlags() & QER_ALPHAFUNC ) ) { int nFunc = 0; float fRef = 0.f; - g_QglTable.m_pfn_qglColor4f( 1.f, 1.f, 1.f, 1.f ); // identity + g_QglTable.m_pfn_qglColor4f( 1.f, 1.f, 1.f, pShader->getTrans() ); // transparency g_QglTable.m_pfn_qglEnable( GL_ALPHA_TEST ); From e35aa24c7420900e849d1d53c755c681f981abd2 Mon Sep 17 00:00:00 2001 From: Willi Schinmeyer Date: Fri, 4 May 2012 10:45:49 +0200 Subject: [PATCH 12/16] Workaround for broken floating windows (XY Window etc. always in front of e.g. surface inspector, properties) --- radiant/mainframe.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 9368292f..cb62e79a 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -2021,8 +2021,10 @@ static void mainframe_unmap( GtkWidget *widget ){ static GtkWidget* create_floating( MainFrame* mainframe ){ GtkWidget *wnd = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - //if (mainframe->CurrentStyle() != MainFrame::eFloating) - gtk_window_set_transient_for( GTK_WINDOW( wnd ), GTK_WINDOW( mainframe->m_pWidget ) ); + //workaround for a bug with set_transient_for in GTK - resulting behaviour is not perfect but better than the bug. + //(see https://bugzilla.gnome.org/show_bug.cgi?id=658975 regarding the bug) + if (mainframe->CurrentStyle() != MainFrame::eFloating) + gtk_window_set_transient_for( GTK_WINDOW( wnd ), GTK_WINDOW( mainframe->m_pWidget ) ); gtk_widget_set_events( wnd, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK ); gtk_signal_connect( GTK_OBJECT( wnd ), "delete_event", GTK_SIGNAL_FUNC( widget_delete_hide ), NULL ); gtk_signal_connect( GTK_OBJECT( wnd ), "destroy", GTK_SIGNAL_FUNC( gtk_widget_destroy ), NULL ); From 57376baa404758f6986b451c1db3a968a295372b Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sat, 5 May 2012 08:46:41 -0500 Subject: [PATCH 13/16] typo fix --- radiant/preferences.cpp | 4 ++-- radiant/preferences.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 7759ed5f..9d70e344 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -2701,7 +2701,7 @@ void PrefsDlg::BuildDialog(){ // end new prefs dialog -void PrefsDlg::LoadTexdefPref( texdef_t* pTexdef, char* pName ){ +void PrefsDlg::LoadTexdefPref( texdef_t* pTexdef, const char* pName ){ char buffer[256]; memset( pTexdef, 0, sizeof( texdef_t ) ); @@ -3412,7 +3412,7 @@ void CGameInstall::Run() { radCreateDirectory(gameFilePath); } - switch ( m_availGame[ m_nComboSelect ] ) { + switch ( m_availGames[ m_nComboSelect ] ) { case GAME_Q2: gameFilePath += "q2.game"; break; diff --git a/radiant/preferences.h b/radiant/preferences.h index 9a120766..6aad97dd 100644 --- a/radiant/preferences.h +++ b/radiant/preferences.h @@ -494,7 +494,7 @@ void UpdateNvidiaAeroHack(); void LoadPrefs(); void SavePrefs(); -void LoadTexdefPref( texdef_t* pTexdef, char* pName ); +void LoadTexdefPref( texdef_t* pTexdef, const char* pName ); PrefsDlg (); virtual ~PrefsDlg (){ From f0cb191f52b0d1b3606a1b241efda739d515254a Mon Sep 17 00:00:00 2001 From: Christian Ratzenhofer Date: Sun, 6 May 2012 17:16:44 +0200 Subject: [PATCH 14/16] Add support for W:ET to the game setup dialog --- config.py | 2 +- radiant/preferences.cpp | 32 ++++++++++++++++++++++++++++++++ radiant/preferences.h | 2 ++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/config.py b/config.py index f872a25e..60dfa45c 100644 --- a/config.py +++ b/config.py @@ -33,7 +33,7 @@ class Config: # platforms for which to assemble a setup self.setup_platforms = [ 'local', 'x86', 'x64', 'win32' ] # paks to assemble in the setup - self.setup_packs = [ 'Q3Pack', 'UrTPack', ] # 'UFOAIPack', 'Q2WPack', 'ReactionPack' ] + self.setup_packs = [ 'Q3Pack', 'UrTPack', 'ETPack', ] # 'UFOAIPack', 'Q2WPack', 'ReactionPack' ] def __repr__( self ): return 'config: target=%s config=%s' % ( self.target_selected, self.config_selected ) diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 9d70e344..b8910ee5 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -3335,6 +3335,9 @@ void CGameInstall::BuildDialog() { case GAME_REACTION: gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Reaction Quake 3" ) ); break; + case GAME_ET: + gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Wolfenstein: Enemy Territory" ) ); + break; } iGame++; } @@ -3443,6 +3446,9 @@ void CGameInstall::Run() { case GAME_REACTION: gameFilePath += "reaction.game"; break; + case GAME_ET: + gameFilePath += "et.game"; + break; } Sys_Printf( "game file: %s\n", gameFilePath.GetBuffer() ); @@ -3584,6 +3590,29 @@ void CGameInstall::Run() { // for a specific game. break; } + case GAME_ET: { +#ifdef _WIN32 + fprintf( fg, " "ENGINE_ATTRIBUTE "=\"ET.exe\"\n"); +#elif __linux__ + fprintf( fg, " "ENGINE_ATTRIBUTE "=\"et\"\n" ); +#endif + fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/"ET_PACK "/game\"\n", g_strAppPath.GetBuffer() ); + fprintf( fg, " prefix=\".etwolf\"\n" ); + Str source = g_strAppPath.GetBuffer(); + source += "installs/"; + source += ET_PACK; + source += "/install/"; + Str dest = m_strEngine.GetBuffer(); + CopyTree( source.GetBuffer(), dest.GetBuffer() ); + // Hardcoded fix for "missing" shaderlist in gamepack + dest += "/etmain/scripts/shaderlist.txt"; + if(CheckFile(dest.GetBuffer()) != PATH_FILE) { + source += "etmain/scripts/default_shaderlist.txt"; + radCopyFile(source.GetBuffer(),dest.GetBuffer()); + } + fprintf( fg, " basegame=\"etmain\"\n" ); + break; + } } fprintf( fg, "/>\n" ); fclose( fg ); @@ -3633,6 +3662,9 @@ void CGameInstall::ScanGames() { if ( stricmp( dirname, REACTION_PACK ) == 0 ) { m_availGames[ iGame++ ] = GAME_REACTION; } + if ( stricmp( dirname, ET_PACK ) == 0 ) { + m_availGames[ iGame++ ] = GAME_ET; + } } Sys_Printf( "No installable games found in: %s\n", pakPaths.GetBuffer() ); diff --git a/radiant/preferences.h b/radiant/preferences.h index 6aad97dd..3d064714 100644 --- a/radiant/preferences.h +++ b/radiant/preferences.h @@ -213,6 +213,7 @@ void Dump(); #define TREMULOUS_PACK "TremulousPack" #define JA_PACK "JAPack" #define REACTION_PACK "ReactionPack" +#define ET_PACK "ETPack" class CGameInstall : public Dialog { public: @@ -236,6 +237,7 @@ enum gameType_e { GAME_TREMULOUS, GAME_JA, GAME_REACTION, + GAME_ET, GAME_COUNT }; From 6476802ae87b1740b96a14514e265bc34a4314e1 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 6 May 2012 15:55:10 -0500 Subject: [PATCH 15/16] dunno what happened there, someone brain farted hard --- tools/quake3/q3map2/image.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/quake3/q3map2/image.c b/tools/quake3/q3map2/image.c index d3b43633..2af46a6f 100644 --- a/tools/quake3/q3map2/image.c +++ b/tools/quake3/q3map2/image.c @@ -98,8 +98,7 @@ typedef struct pngBuffer_s { byte *buffer; int size, offset; -} -pngBuffer_t; +} pngBuffer_t; void PNGReadData( png_struct *png, png_byte *buffer, png_size_t size ){ pngBuffer_t *pb = (pngBuffer_t*) png_get_io_ptr( png ); @@ -123,7 +122,7 @@ void PNGReadData( png_struct *png, png_byte *buffer, png_size_t size ){ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, int *height ){ png_struct *png; png_info *info, *end; - pngBuffer_t *pb = (pngBuffer_t*) png_get_io_ptr( png ); + pngBuffer_t pb; int i, bitDepth, colorType, channels; png_uint_32 w, h; byte **rowPointers; @@ -166,11 +165,10 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in } /* set read callback */ - pb->buffer = buffer; - pb->size = size; - pb->offset = 0; - png_set_read_fn( png, &pb, PNGReadData ); - //png->io_ptr = &pb; /* hack! */ + pb.buffer = buffer; + pb.size = size; + pb.offset = 0; + png_set_read_fn( png, (void*)&pb, PNGReadData ); /* set error longjmp */ if ( setjmp( png_jmpbuf(png) ) ) { From 9b5ba1fe10d7eba4db1588c2a4926829c465dc76 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 6 May 2012 16:59:07 -0500 Subject: [PATCH 16/16] error check and bail if permission denied during gamepack install --- libs/missing.h | 6 ++-- radiant/missing.cpp | 77 ++++++++++++++++++++++++++++++----------- radiant/preferences.cpp | 26 +++++++------- 3 files changed, 73 insertions(+), 36 deletions(-) diff --git a/libs/missing.h b/libs/missing.h index 2ba03d14..9a1b121f 100644 --- a/libs/missing.h +++ b/libs/missing.h @@ -209,7 +209,7 @@ DIR * findHandle; #endif }; -bool CopyTree( const char* source, const char* dest ); +bool radCopyTree( const char* source, const char* dest, bool fatal_on_error = true ); typedef enum { PATH_FAIL, // stat call failed (does not exist is likely) @@ -220,7 +220,7 @@ typedef enum { // check a path for existence, return directory / file EPathCheck CheckFile( const char *path ); -bool radCreateDirectory( const char *directory ); -bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ); +bool radCreateDirectory( const char *directory, bool fatal_on_error = true ); +bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName, bool fatal_on_error = true ); #endif // _MISSING_H_ diff --git a/radiant/missing.cpp b/radiant/missing.cpp index 6c7e4a7f..a60b2944 100644 --- a/radiant/missing.cpp +++ b/radiant/missing.cpp @@ -36,6 +36,7 @@ #include "missing.h" #include "qsysprintf.h" +#include "qe3.h" #if defined ( __linux__ ) || defined ( __APPLE__ ) @@ -47,7 +48,7 @@ #include #include -bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ){ +bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName, bool fatal_on_error ){ FILE *src, *dst; void* buf; int l; @@ -59,12 +60,20 @@ bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ){ src = fopen( realsrc, "rb" ); if ( !src ) { - return false; + if ( fatal_on_error ) { + Error( "Failed to open source for copy: %s\n", realsrc ); + } + Sys_Printf( "Failed to open source for copy: %s\n", realsrc ); + return false; } dst = fopen( realdest, "wb" ); if ( !dst ) { - fclose( src ); - return false; + if ( fatal_on_error ) { + Error( "Failed to open destination for copy: %s\n", realdest ); + } + Sys_Printf( "Failed to open destination for copy: %s\n", realdest ); + fclose( src ); + return false; } fseek( src, 0, SEEK_END ); @@ -79,6 +88,12 @@ bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ){ } } } + if ( !ret ) { + if ( fatal_on_error ) { + Error( "short read or short write while copying %s to %s\n", realsrc, realdest ); + } + Sys_Printf( "short read or short write while copying %s to %s\n", realsrc, realdest ); + } g_free( buf ); fclose( src ); @@ -87,12 +102,15 @@ bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ){ return ret; } -bool radCreateDirectory( const char *directory ) { - if ( mkdir( directory, 0777 ) == -1 ) { - Sys_Printf( "mkdir %s failed\n", directory ); - return false; - } - return true; +bool radCreateDirectory( const char *directory, bool fatal_on_error ) { + if ( mkdir( directory, 0777 ) >= 0 ) { + return true; + } + if ( fatal_on_error ) { + Error( "mkdir %s failed - check your permissions", directory ); + } + Sys_Printf( "mkdir %s failed - check your permissions\n", directory ); + return false; } int GetFullPathName( const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart ){ @@ -219,17 +237,31 @@ EPathCheck CheckFile( const char *path ) { return PATH_FILE; } -bool radCreateDirectory( const char *directory ) { - return ( CreateDirectory( directory, NULL ) != false ); +bool radCreateDirectory( const char *directory, bool fatal_on_error ) { + if ( CreateDirectory( directory, NULL ) ) { + return true; + } + if ( fatal_on_error ) { + Error( "mkdir %s failed - check your permissions", directory ); + } + Sys_Printf( "mkdir %s failed - check your permissions\n", directory ); + return false; } -bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName ) { - return ( CopyFile( lpExistingFileName, lpNewFileName, FALSE ) != false ); +bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName, bool fatal_on_error ) { + if ( CopyFile( lpExistingFileName, lpNewFileName, FALSE ) ) { + return true; + } + if ( fatal_on_error ) { + Error( "copy %s %s failed - check your permissions", lpExistingFileName, lpNewFileName ); + } + Sys_Printf( "copy %s %s failed - check your permissions\n", lpExistingFileName, lpNewFileName ); + return false; } #endif -bool CopyTree( const char *source, const char *dest ) { +bool radCopyTree( const char *source, const char *dest, bool fatal_on_error ) { Str srcEntry; Str dstEntry; const char *dirname; @@ -249,23 +281,28 @@ bool CopyTree( const char *source, const char *dest ) { dstEntry += "/"; dstEntry += dirname; switch ( CheckFile( srcEntry.GetBuffer() ) ) { + case PATH_FAIL: { + if ( fatal_on_error ) { + Error( "%s does not exist. check your permissions", srcEntry.GetBuffer() ); + } + } case PATH_DIRECTORY: { if ( CheckFile( dstEntry.GetBuffer() ) == PATH_FAIL ) { - if ( !radCreateDirectory( dstEntry.GetBuffer() ) ) { - Sys_Printf( "create directory %s failed\n", dstEntry.GetBuffer() ); + Sys_Printf( "Create directory %s\n", dstEntry.GetBuffer() ); + if ( !radCreateDirectory( dstEntry.GetBuffer(), fatal_on_error ) ) { return false; } } bool ret; - ret = CopyTree( srcEntry.GetBuffer(), dstEntry.GetBuffer() ); + ret = radCopyTree( srcEntry.GetBuffer(), dstEntry.GetBuffer(), fatal_on_error ); if ( !ret ) { return false; } break; } case PATH_FILE: { - Sys_Printf( "copy %s -> %s\n", srcEntry.GetBuffer(), dstEntry.GetBuffer() ); - bool ret = radCopyFile( srcEntry.GetBuffer(), dstEntry.GetBuffer() ); + Sys_Printf( "Copy %s -> %s\n", srcEntry.GetBuffer(), dstEntry.GetBuffer() ); + bool ret = radCopyFile( srcEntry.GetBuffer(), dstEntry.GetBuffer(), fatal_on_error ); if ( !ret ) { return false; } diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index b8910ee5..08ff05c4 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -3411,8 +3411,8 @@ void CGameInstall::Run() { // write out the game file Str gameFilePath = g_strAppPath.GetBuffer(); gameFilePath += "games/"; - if(CheckFile(gameFilePath) != PATH_DIRECTORY) { - radCreateDirectory(gameFilePath); + if ( CheckFile( gameFilePath ) != PATH_DIRECTORY ) { + radCreateDirectory( gameFilePath ); } switch ( m_availGames[ m_nComboSelect ] ) { @@ -3469,7 +3469,7 @@ void CGameInstall::Run() { source += Q2_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"baseq2\"\n" ); break; } @@ -3481,7 +3481,7 @@ void CGameInstall::Run() { source += Q3_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); // Hardcoded fix for "missing" shaderlist in gamepack dest += "/baseq3/scripts/shaderlist.txt"; if(CheckFile(dest.GetBuffer()) != PATH_FILE) { @@ -3499,7 +3499,7 @@ void CGameInstall::Run() { source += URT_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"q3ut4\"\n" ); break; } @@ -3511,7 +3511,7 @@ void CGameInstall::Run() { source += UFOAI_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"base\"\n" ); break; } @@ -3523,7 +3523,7 @@ void CGameInstall::Run() { source += Q2W_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"default\"\n" ); break; } @@ -3535,7 +3535,7 @@ void CGameInstall::Run() { source += WARSOW_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"basewsw\"\n" ); break; } @@ -3547,7 +3547,7 @@ void CGameInstall::Run() { source += NEXUIZ_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"data\"\n" ); break; } @@ -3559,7 +3559,7 @@ void CGameInstall::Run() { source += TREMULOUS_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"base\"\n" ); break; } @@ -3571,7 +3571,7 @@ void CGameInstall::Run() { source += JA_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"base\"\n" ); break; } @@ -3583,7 +3583,7 @@ void CGameInstall::Run() { source += REACTION_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); fprintf( fg, " basegame=\"Boomstick\"\n" ); fprintf( fg, " default_scale=\"0.5\"\n" ); // Superfluous because the default is already 0.5, // but demonstrates how to set the default texture scale @@ -3603,7 +3603,7 @@ void CGameInstall::Run() { source += ET_PACK; source += "/install/"; Str dest = m_strEngine.GetBuffer(); - CopyTree( source.GetBuffer(), dest.GetBuffer() ); + radCopyTree( source.GetBuffer(), dest.GetBuffer() ); // Hardcoded fix for "missing" shaderlist in gamepack dest += "/etmain/scripts/shaderlist.txt"; if(CheckFile(dest.GetBuffer()) != PATH_FILE) {