mirror of https://git.do.srb2.org/STJr/ZenNode.git
Initial commit
This commit is contained in:
commit
2e174e655d
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,341 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: level.hpp
|
||||
// Date: 26-Oct-1994
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Object classes for manipulating Doom Maps
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef LEVEL_HPP_
|
||||
#define LEVEL_HPP_
|
||||
|
||||
#if ! defined ( COMMON_HPP_ )
|
||||
#include "common.hpp"
|
||||
#endif
|
||||
|
||||
#if ! defined ( WAD_HPP_ )
|
||||
#include "wad.hpp"
|
||||
#endif
|
||||
|
||||
#include "thing.hpp"
|
||||
#include "lineDef.hpp"
|
||||
|
||||
struct wThing1 {
|
||||
INT16 xPos; // x position
|
||||
INT16 yPos; // y position
|
||||
UINT16 angle; // direction
|
||||
UINT16 type; // thing type
|
||||
UINT16 attr; // attributes of thing
|
||||
};
|
||||
|
||||
struct wThing2 { // HEXEN
|
||||
UINT16 tid; // Thing ID - for scripts & specials
|
||||
INT16 xPos; // x position
|
||||
INT16 yPos; // y position
|
||||
UINT16 altitude; // starting altitude
|
||||
UINT16 angle; // direction
|
||||
UINT16 type; // thing type
|
||||
UINT16 attr; // attributes of thing
|
||||
UINT8 special; // special type
|
||||
UINT8 arg [5]; // special arguments
|
||||
};
|
||||
|
||||
struct wThing {
|
||||
INT16 xPos; // x position
|
||||
INT16 yPos; // y position
|
||||
UINT16 angle; // in degrees not BAM
|
||||
UINT16 type; // thing type
|
||||
UINT16 attr; // attributes of thing
|
||||
UINT16 tid; // Thing ID - for scripts & specials
|
||||
UINT16 altitude; // starting altitude
|
||||
UINT8 special; // special type
|
||||
UINT8 arg [5]; // special arguments
|
||||
};
|
||||
|
||||
struct wLineDef1 {
|
||||
UINT16 start; // from this vertex ...
|
||||
UINT16 end; // ... to this vertex
|
||||
UINT16 flags;
|
||||
UINT16 type;
|
||||
UINT16 tag; // crossing this linedef activates the sector with the same tag
|
||||
UINT16 sideDef[2]; // sidedef
|
||||
};
|
||||
|
||||
struct wLineDef2 { // HEXEN
|
||||
UINT16 start; // from this vertex ...
|
||||
UINT16 end; // ... to this vertex
|
||||
UINT16 flags;
|
||||
UINT8 special; // special type
|
||||
UINT8 arg [5]; // special arguments
|
||||
UINT16 sideDef[2]; // sidedef
|
||||
};
|
||||
|
||||
struct wLineDef {
|
||||
UINT16 start; // from this vertex ...
|
||||
UINT16 end; // ... to this vertex
|
||||
UINT16 flags;
|
||||
UINT16 type;
|
||||
UINT16 tag; // crossing this linedef activates the sector with the same tag
|
||||
UINT16 sideDef[2]; // sidedef
|
||||
UINT8 special; // special type
|
||||
UINT8 arg [5]; // special arguments
|
||||
};
|
||||
|
||||
#define NO_SIDEDEF (( UINT16 ) -1 )
|
||||
#define RIGHT_SIDEDEF (( UINT16 ) 0 )
|
||||
#define LEFT_SIDEDEF (( UINT16 ) 1 )
|
||||
|
||||
#define EMPTY_TEXTURE 0x002D // UINT16 version of ASCII "-"
|
||||
|
||||
struct wSideDef {
|
||||
INT16 xOff; // X offset for texture
|
||||
INT16 yOff; // Y offset for texture
|
||||
char text1[MAX_LUMP_NAME]; // texture name for the part above
|
||||
char text2[MAX_LUMP_NAME]; // texture name for the part below
|
||||
char text3[MAX_LUMP_NAME]; // texture name for the regular part
|
||||
UINT16 sector; // adjacent sector
|
||||
};
|
||||
|
||||
struct wVertex {
|
||||
INT16 x; // X coordinate
|
||||
INT16 y; // Y coordinate
|
||||
};
|
||||
|
||||
struct wSector {
|
||||
INT16 floorh; // floor height
|
||||
INT16 ceilh; // ceiling height
|
||||
char floorTexture[MAX_LUMP_NAME]; // floor texture
|
||||
char ceilTexture[MAX_LUMP_NAME]; // ceiling texture
|
||||
UINT16 light; // light level (0-255)
|
||||
UINT16 special; // special behaviour (0 = normal, 9 = secret, ...)
|
||||
UINT16 trigger; // sector activated by a linedef with the same tag
|
||||
};
|
||||
|
||||
struct wSegs {
|
||||
UINT16 start; // from this vertex ...
|
||||
UINT16 end; // ... to this vertex
|
||||
UINT16 angle; // angle (0 = east, 16384 = north, ...)
|
||||
UINT16 lineDef; // linedef that this seg goes along*/
|
||||
UINT16 flip; // true if not the same direction as linedef
|
||||
UINT16 offset; // distance from starting point
|
||||
};
|
||||
|
||||
struct wSSector {
|
||||
UINT16 num; // number of Segs in this Sub-Sector
|
||||
UINT16 first; // first Seg
|
||||
};
|
||||
|
||||
struct wBound {
|
||||
INT16 maxy, miny;
|
||||
INT16 minx, maxx; // bounding rectangle
|
||||
};
|
||||
|
||||
struct wNode {
|
||||
INT16 x, y; // starting point
|
||||
INT16 dx, dy; // offset to ending point
|
||||
wBound side[2];
|
||||
UINT16 child[2]; // Node or SSector (if high bit is set)
|
||||
};
|
||||
|
||||
struct wReject {
|
||||
UINT16 dummy;
|
||||
};
|
||||
|
||||
struct wBlockMap {
|
||||
INT16 xOrigin;
|
||||
INT16 yOrigin;
|
||||
UINT16 noColumns;
|
||||
UINT16 noRows;
|
||||
// UINT16 data [];
|
||||
};
|
||||
|
||||
class DoomLevel {
|
||||
|
||||
struct sLevelLump {
|
||||
bool changed;
|
||||
int byteOrder;
|
||||
int elementSize;
|
||||
int elementCount;
|
||||
UINT32 dataSize;
|
||||
void *rawData;
|
||||
|
||||
sLevelLump ();
|
||||
};
|
||||
|
||||
WAD *m_Wad;
|
||||
wLumpName m_Name;
|
||||
|
||||
bool m_IsHexen;
|
||||
const char *m_Title;
|
||||
const char *m_Music;
|
||||
int m_Cluster;
|
||||
|
||||
wThing *m_ThingData;
|
||||
wLineDef *m_LineDefData;
|
||||
|
||||
sLevelLump m_Map;
|
||||
sLevelLump m_Thing;
|
||||
sLevelLump m_LineDef;
|
||||
sLevelLump m_SideDef;
|
||||
sLevelLump m_Vertex;
|
||||
sLevelLump m_Sector;
|
||||
sLevelLump m_Segs;
|
||||
sLevelLump m_SubSector;
|
||||
sLevelLump m_Node;
|
||||
sLevelLump m_Reject;
|
||||
sLevelLump m_BlockMap;
|
||||
sLevelLump m_Behavior;
|
||||
|
||||
static void ConvertRaw1ToThing ( int, wThing1 *, wThing * );
|
||||
static void ConvertRaw2ToThing ( int, wThing2 *, wThing * );
|
||||
static void ConvertThingToRaw1 ( int, wThing *, wThing1 * );
|
||||
static void ConvertThingToRaw2 ( int, wThing *, wThing2 * );
|
||||
|
||||
static void ConvertRaw1ToLineDef ( int, wLineDef1 *, wLineDef * );
|
||||
static void ConvertRaw2ToLineDef ( int, wLineDef2 *, wLineDef * );
|
||||
static void ConvertLineDefToRaw1 ( int, wLineDef *, wLineDef1 * );
|
||||
static void ConvertLineDefToRaw2 ( int, wLineDef *, wLineDef2 * );
|
||||
|
||||
void ReplaceVertices ( int *, wVertex *, int );
|
||||
|
||||
void DetermineType ();
|
||||
|
||||
bool Load ();
|
||||
bool LoadHexenInfo ();
|
||||
|
||||
bool LoadThings ( bool );
|
||||
bool LoadLineDefs ( bool );
|
||||
|
||||
void StoreThings ();
|
||||
void StoreLineDefs ();
|
||||
|
||||
void NewEntry ( sLevelLump *, int, void * );
|
||||
|
||||
bool ReadEntry ( sLevelLump *, const char *, const wadDirEntry *, const wadDirEntry *, bool );
|
||||
bool UpdateEntry ( sLevelLump *, const char *, const char *, bool );
|
||||
|
||||
void AdjustByteOrderMap ( int );
|
||||
void AdjustByteOrderThing ( int );
|
||||
void AdjustByteOrderLineDef ( int );
|
||||
void AdjustByteOrderSideDef ( int );
|
||||
void AdjustByteOrderVertex ( int );
|
||||
void AdjustByteOrderSector ( int );
|
||||
void AdjustByteOrderSegs ( int );
|
||||
void AdjustByteOrderSubSector ( int );
|
||||
void AdjustByteOrderNode ( int );
|
||||
void AdjustByteOrderReject ( int );
|
||||
void AdjustByteOrderBlockMap ( int );
|
||||
void AdjustByteOrderBehavior ( int );
|
||||
|
||||
void AdjustByteOrder ( int );
|
||||
|
||||
void CleanUpEntry ( sLevelLump * );
|
||||
void CleanUp ();
|
||||
|
||||
public:
|
||||
|
||||
DoomLevel ( const char *, WAD *, bool = true );
|
||||
~DoomLevel ();
|
||||
|
||||
const WAD *GetWAD () const { return m_Wad; }
|
||||
|
||||
const char *Name () const { return m_Name; }
|
||||
const char *Title () const { return m_Title ? m_Title : m_Name; }
|
||||
const char *Music () const { return m_Music ? m_Music : NULL; }
|
||||
int MapCluster () const { return m_Cluster; }
|
||||
|
||||
int ThingCount () const { return m_Thing.elementCount; }
|
||||
int LineDefCount () const { return m_LineDef.elementCount; }
|
||||
int SideDefCount () const { return m_SideDef.elementCount; }
|
||||
int VertexCount () const { return m_Vertex.elementCount; }
|
||||
int SectorCount () const { return m_Sector.elementCount; }
|
||||
int SegCount () const { return m_Segs.elementCount; }
|
||||
int SubSectorCount () const { return m_SubSector.elementCount; }
|
||||
int NodeCount () const { return m_Node.elementCount; }
|
||||
int RejectSize () const { return m_Reject.dataSize; }
|
||||
int BlockMapSize () const { return m_BlockMap.dataSize; }
|
||||
int BehaviorSize () const { return m_Behavior.dataSize; }
|
||||
|
||||
const wThing *GetThings () const { return m_ThingData; }
|
||||
const wLineDef *GetLineDefs () const { return m_LineDefData; }
|
||||
const wSideDef *GetSideDefs () const { return ( wSideDef * ) m_SideDef.rawData; }
|
||||
const wVertex *GetVertices () const { return ( wVertex * ) m_Vertex.rawData; }
|
||||
const wSector *GetSectors () const { return ( wSector * ) m_Sector.rawData; }
|
||||
const wSegs *GetSegs () const { return ( wSegs * ) m_Segs.rawData; }
|
||||
const wSSector *GetSubSectors () const { return ( wSSector * ) m_SubSector.rawData; }
|
||||
const wNode *GetNodes () const { return ( wNode * ) m_Node.rawData; }
|
||||
const wReject *GetReject () const { return ( wReject * ) m_Reject.rawData; }
|
||||
const wBlockMap *GetBlockMap () const { return ( wBlockMap * ) m_BlockMap.rawData; }
|
||||
const UINT8 *GetBehavior () const { return ( UINT8 * ) m_Behavior.rawData; }
|
||||
|
||||
void NewThings ( int, wThing * );
|
||||
void NewLineDefs ( int, wLineDef * );
|
||||
void NewSideDefs ( int, wSideDef * );
|
||||
void NewVertices ( int, wVertex * );
|
||||
void NewSectors ( int, wSector * );
|
||||
void NewSegs ( int, wSegs * );
|
||||
void NewSubSectors ( int, wSSector * );
|
||||
void NewNodes ( int, wNode * );
|
||||
void NewReject ( int, UINT8 * );
|
||||
void NewBlockMap ( int, wBlockMap * );
|
||||
void NewBehavior ( int, char * );
|
||||
|
||||
bool IsValid ( bool, bool = true ) const;
|
||||
bool IsDirty () const;
|
||||
|
||||
void TrimVertices ();
|
||||
void PackVertices ();
|
||||
|
||||
void PackSideDefs ();
|
||||
void UnPackSideDefs ();
|
||||
|
||||
bool UpdateWAD ();
|
||||
void AddToWAD ( WAD *wad );
|
||||
|
||||
sThingDesc *FindThing ( int type );
|
||||
static sLineDefDesc *FindLineDef ( int type );
|
||||
|
||||
sThingDesc *GetThing ( int index );
|
||||
static sLineDefDesc *GetLineDef ( int index );
|
||||
};
|
||||
|
||||
#if ( BYTE_ORDER == LITTLE_ENDIAN )
|
||||
|
||||
inline void DoomLevel::AdjustByteOrderMap ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderThing ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderLineDef ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderSideDef ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderVertex ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderSector ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderSegs ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderSubSector ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderNode ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderReject ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderBlockMap ( int ) {}
|
||||
inline void DoomLevel::AdjustByteOrderBehavior ( int ) {}
|
||||
|
||||
inline void DoomLevel::AdjustByteOrder ( int ) {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,159 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: lineDef.hpp
|
||||
// Date: 23-August-1995
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Object classes for manipulating Doom Map LineDefs
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef LINEDEF_HPP_
|
||||
#define LINEDEF_HPP_
|
||||
|
||||
#if ! defined ( LEVEL_HPP_ )
|
||||
#include "level.hpp"
|
||||
#endif
|
||||
|
||||
// WAD LINEDEF Flags
|
||||
#define LDF_IMPASSABLE 0x0001
|
||||
#define LDF_BLOCK_MONSTERS 0x0002
|
||||
#define LDF_TWO_SIDED 0x0004
|
||||
#define LDF_UPPER_UNPEGGED 0x0008
|
||||
#define LDF_LOWER_UNPEGGED 0x0010
|
||||
#define LDF_SECRET 0x0020
|
||||
#define LDF_BLOCK_SOUND 0x0040
|
||||
#define LDF_NOT_ON_MAP 0x0080
|
||||
#define LDF_ALREADY_ON_MAP 0x0100
|
||||
|
||||
enum LD_LINE_CLASS {
|
||||
LDC_NONE, // "--"
|
||||
LDC_SPECIAL, // "Special"
|
||||
LDC_DOOR, // "Door"
|
||||
LDC_REMOTE, // "Remote Door"
|
||||
LDC_CEILING, // "Ceiling"
|
||||
LDC_LIFT, // "Lift"
|
||||
LDC_FLOOR, // "Floor"
|
||||
LDC_STAIRS, // "Stairs"
|
||||
LDC_MOVE, // "Moving Floor"
|
||||
LDC_CRUSH, // "Crushing Ceiling"
|
||||
LDC_EXIT, // "Exit"
|
||||
LDC_TELEPORT, // "Teleporter"
|
||||
LDC_LIGHT, // "Light"
|
||||
LDC_UNKNOWN, // "???"
|
||||
};
|
||||
|
||||
enum LD_LINE_SPEED {
|
||||
LDS_NONE,
|
||||
LDS_SLOW,
|
||||
LDS_MED,
|
||||
LDS_FAST,
|
||||
LDS_TURBO
|
||||
};
|
||||
|
||||
enum LD_LINE_ACTION {
|
||||
LDA_NONE,
|
||||
LDA_SCROLL,
|
||||
LDA_OPEN,
|
||||
LDA_CLOSE,
|
||||
LDA_RAISE,
|
||||
LDA_LOWER,
|
||||
LDA_START,
|
||||
LDA_STOP,
|
||||
LDA_CHANGE,
|
||||
LDA_TELEPORT,
|
||||
LDA_END,
|
||||
LDA_END_SECRET
|
||||
};
|
||||
|
||||
enum LD_LINE_EFFECTS {
|
||||
LDE_NONE = 0x00000000,
|
||||
|
||||
LDE_NEEDTAG = 0x80000000,
|
||||
|
||||
LDE_LOCK = 0x40000000,
|
||||
|
||||
LDE_MONSTER = 0x20000000,
|
||||
LDE_MONSTER_ONLY = 0x10000000,
|
||||
|
||||
LDE_TRIGGER_MODEL = 0x08000000,
|
||||
LDE_NUMERIC_MODEL = 0x04000000,
|
||||
LDE_MODEL_MASK = 0x0C000000,
|
||||
|
||||
LDE_TX_TEXTURE = 0x02000000,
|
||||
LDE_TX_SPECIAL = 0x01000000,
|
||||
LDE_TX_MASK = 0x03000000,
|
||||
|
||||
LDE_MAX = 0x00800000,
|
||||
LDE_MIN = 0x00400000,
|
||||
|
||||
LDE_MV_HIGHEST = 0x00C00000,
|
||||
LDE_MV_NEXT_HIGHEST = 0x00800000,
|
||||
LDE_MV_LOWEST = 0x00400000,
|
||||
|
||||
LDE_MV_SHORTEST = 0x00300000,
|
||||
LDE_MV_FLOOR = 0x00200000,
|
||||
LDE_MV_CEILING = 0x00100000,
|
||||
|
||||
LDE_MV_EXCLUSIVE = 0x00080000,
|
||||
LDE_MV_INCLUSIVE = 0x00040000,
|
||||
|
||||
LDE_SLOW_HURT = 0x00020000,
|
||||
LDE_FAST_HURT = 0x00010000,
|
||||
LDE_CRUSH = 0x00008000,
|
||||
LDE_SILENT = 0x00004000,
|
||||
LDE_BLINKING = 0x00002000,
|
||||
|
||||
LDE_KEY_BLUE = 0x00000C00,
|
||||
LDE_KEY_YELLOW = 0x00000800,
|
||||
LDE_KEY_RED = 0x00000400,
|
||||
LDE_KEY_MASK = 0x00000C00,
|
||||
|
||||
LDE_MODIFIER_MASK = 0x000003FF
|
||||
};
|
||||
|
||||
#define LDE_TX ( LDE_TRIGGER_MODEL | LDE_TX_TEXTURE )
|
||||
#define LDE_TXP ( LDE_TRIGGER_MODEL | LDE_TX_TEXTURE | LDE_TX_SPECIAL )
|
||||
#define LDE_NXP ( LDE_NUMERIC_MODEL | LDE_TX_TEXTURE | LDE_TX_SPECIAL )
|
||||
#define LDE_HE ( LDE_MV_HIGHEST | LDE_MV_EXCLUSIVE )
|
||||
#define LDE_HEF ( LDE_MV_HIGHEST | LDE_MV_EXCLUSIVE | LDE_MV_FLOOR )
|
||||
#define LDE_HEC ( LDE_MV_HIGHEST | LDE_MV_EXCLUSIVE | LDE_MV_CEILING )
|
||||
#define LDE_LE ( LDE_MV_LOWEST | LDE_MV_EXCLUSIVE )
|
||||
#define LDE_LEF ( LDE_MV_LOWEST | LDE_MV_EXCLUSIVE | LDE_MV_FLOOR )
|
||||
#define LDE_LIC ( LDE_MV_LOWEST | LDE_MV_INCLUSIVE | LDE_MV_CEILING )
|
||||
#define LDE_nhEF ( LDE_MV_NEXT_HIGHEST | LDE_MV_EXCLUSIVE | LDE_MV_FLOOR )
|
||||
#define LDE_F ( LDE_MV_FLOOR )
|
||||
#define LDE_NUM(x) ((x) & LDE_MODIFIER_MASK )
|
||||
|
||||
struct sLineDefDesc {
|
||||
INT16 Type;
|
||||
UINT8 Class;
|
||||
const char *Trigger;
|
||||
UINT8 Speed;
|
||||
UINT8 Duration;
|
||||
UINT8 Action;
|
||||
UINT32 Effects;
|
||||
|
||||
const char *GetClass ();
|
||||
const char *GetDescription ();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,100 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: thing.hpp
|
||||
// Date: 23-August-1995
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Object classes for manipulating Doom Map Things
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef THING_HPP_
|
||||
#define THING_HPP_
|
||||
|
||||
#if ! defined ( LEVEL_HPP_ )
|
||||
#include "level.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef SHORT
|
||||
typedef short SHORT;
|
||||
#endif
|
||||
|
||||
#define THING_SKILL_1_2 0x0001
|
||||
#define THING_SKILL_3 0x0002
|
||||
#define THING_SKILL_4_5 0x0004
|
||||
#define THING_DEAF 0x0008
|
||||
#define THING_MULTIPLAYER 0x0010
|
||||
#define THING_a 0x0020
|
||||
#define THING_b 0x0040
|
||||
#define THING_c 0x0080
|
||||
#define THING_d 0x0100
|
||||
#define THING_e 0x0200
|
||||
#define THING_f 0x0400
|
||||
|
||||
|
||||
#define TP_NONE 0x00000
|
||||
#define TP_BLOCK 0x00001 // Blocks the player
|
||||
#define TP_PICK 0x00002 // Can be picked up
|
||||
#define TP_SOUND 0x00004 // Sound only: invisible, can be outside of map
|
||||
#define TP_INVIS 0x00008 // Invisible or blurred
|
||||
#define TP_FLOAT 0x00010 // Floats or hangs from the ceiling
|
||||
#define TP_LIGHT 0x00020 // Can be seen in a dark room
|
||||
#define TP_ITEM 0x00040 // Counts towards the item ratio at the end
|
||||
#define TP_KILL 0x00080 // Counts towards the kill ratio at the end
|
||||
#define TP_PLAYER 0x00100 // Player starting point
|
||||
#define TP_HEALTH ( 0x00200 | TP_PICK )
|
||||
#define TP_ARTIFACT ( 0x00400 | TP_PICK | TP_ITEM ) // Artifact
|
||||
#define TP_ARMOR ( 0x00800 | TP_PICK
|
||||
#define TP_WEAPON ( 0x01000 | TP_PICK | TP_ITEM ) // Weapon
|
||||
#define TP_AMMO 0x02000 // Ammunition
|
||||
#define TP_KEY ( 0x04000 | TP_PICK | TP_ITEM )
|
||||
#define TP_MONSTER ( 0x08000 | TP_BLOCK | TP_KILL )
|
||||
#define TP_BAD -1 // Invalid Thing - should not be used
|
||||
|
||||
#define TP_POLYOBJ 0x10000
|
||||
|
||||
#define TP_BONUS ( TP_PICK | TP_ITEM )
|
||||
#define TP_DECORATE TP_BLOCK
|
||||
#define TP_CORPSE TP_DECORATE
|
||||
|
||||
struct sThingDesc {
|
||||
SHORT Type;
|
||||
const char *Name;
|
||||
const char *Sprite;
|
||||
const char *Sequence;
|
||||
SHORT Radius;
|
||||
SHORT Height;
|
||||
SHORT Mass;
|
||||
SHORT Health;
|
||||
SHORT Speed;
|
||||
SHORT Damage;
|
||||
int Properties;
|
||||
};
|
||||
|
||||
/*
|
||||
Bullets 10
|
||||
Shotgun 70 ( 7 pellets * 10 )
|
||||
Plasma 20
|
||||
Rockets 100
|
||||
BFG 1000
|
||||
*/
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,322 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: wad.hpp
|
||||
// Date: 26-Oct-1994
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Object classes for manipulating Doom WAD files
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
// 04-25-01 Added little/big endian conversions
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef WAD_HPP_
|
||||
#define WAD_HPP_
|
||||
|
||||
#if ! defined ( COMMON_HPP_ )
|
||||
#include "common.hpp"
|
||||
#endif
|
||||
|
||||
#if ! defined ( __STDIO_H )
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if ( BYTE_ORDER == LITTLE_ENDIAN )
|
||||
const UINT32 IWAD_ID = 0x44415749; // ASCII - 'IWAD'
|
||||
const UINT32 PWAD_ID = 0x44415750; // ASCII - 'PWAD'
|
||||
#else
|
||||
const UINT32 IWAD_ID = 0x49574144; // ASCII - 'IWAD'
|
||||
const UINT32 PWAD_ID = 0x50574144; // ASCII - 'PWAD'
|
||||
|
||||
extern UINT32 swap_uint32 ( const unsigned char *ptr );
|
||||
extern UINT16 swap_uint16 ( const unsigned char *ptr );
|
||||
#endif
|
||||
|
||||
#define IS_TYPE(x,y) (( * ( UINT32 * ) ( x )) == (( UINT32 ) y ))
|
||||
|
||||
#define MAX_LUMP_NAME 8
|
||||
|
||||
enum eLumpType {
|
||||
wl_UNCHECKED,
|
||||
wl_UNKNOWN,
|
||||
wl_PALETTE,
|
||||
wl_COLORMAP,
|
||||
wl_DEMO,
|
||||
wl_TEXTURE_LIST,
|
||||
wl_PATCH_NAMES,
|
||||
wl_MIDI_MAPPING,
|
||||
wl_GRAVIS_PATCH,
|
||||
wl_MAP_NAME,
|
||||
wl_MAP_DATA,
|
||||
wl_PC_SPEAKER,
|
||||
wl_SOUND_EFFECT,
|
||||
wl_MUSIC,
|
||||
wl_FLAT,
|
||||
wl_PATCH,
|
||||
wl_SPRITE,
|
||||
wl_GRAPHIC,
|
||||
wl_SCREEN_SHOT,
|
||||
wl_TEXT_SCREEN,
|
||||
wl_SOUND_INFO,
|
||||
wl_SCRIPT,
|
||||
wl_SPECIAL
|
||||
};
|
||||
|
||||
enum eWadType {
|
||||
wt_UNKNOWN,
|
||||
wt_DOOM,
|
||||
wt_DOOM2,
|
||||
wt_HERETIC,
|
||||
wt_HEXEN
|
||||
};
|
||||
|
||||
enum eWadStyle {
|
||||
wst_UNKNOWN,
|
||||
wst_FORMAT_1, // DOOM / Heretic
|
||||
wst_FORMAT_2, // DOOM ][
|
||||
wst_FORMAT_3 // Hexen
|
||||
};
|
||||
|
||||
enum eWadStatus {
|
||||
ws_UNKNOWN,
|
||||
ws_OK,
|
||||
ws_CANT_READ,
|
||||
ws_CANT_WRITE,
|
||||
ws_INVALID_WAD,
|
||||
ws_INVALID_FILE,
|
||||
ws_SEEK_ERROR,
|
||||
ws_READ_ERROR,
|
||||
ws_WRITE_ERROR
|
||||
};
|
||||
|
||||
struct wadHeader {
|
||||
char type [4];
|
||||
UINT32 dirSize; // number of Lumps in WAD
|
||||
UINT32 dirStart; // offset to start of directory
|
||||
};
|
||||
|
||||
typedef char wLumpName [ MAX_LUMP_NAME ];
|
||||
|
||||
struct wadDirEntry {
|
||||
UINT32 offset; // offset to start of data
|
||||
UINT32 size; // byte size of data
|
||||
wLumpName name; // name of data block
|
||||
};
|
||||
|
||||
struct wadDirInfo {
|
||||
UINT8 *cacheData;
|
||||
UINT8 *newData;
|
||||
eLumpType type;
|
||||
};
|
||||
|
||||
class wadList;
|
||||
|
||||
class wadFilter {
|
||||
public:
|
||||
virtual const char *getFileSpec () const = 0;
|
||||
virtual bool isRecognized ( UINT32, void * ) const = 0;
|
||||
virtual bool isRecognized ( const char * ) const = 0;
|
||||
virtual bool readData ( FILE *, UINT32 *, void ** ) const = 0;
|
||||
virtual bool writeData ( FILE *, UINT32, void * ) const = 0;
|
||||
};
|
||||
|
||||
class WAD {
|
||||
|
||||
char *m_Name;
|
||||
FILE *m_File;
|
||||
wadList *m_List;
|
||||
|
||||
bool m_bValid;
|
||||
bool m_bRegistered;
|
||||
bool m_bDirChanged; // wadDirEntry added/deleted
|
||||
|
||||
wadHeader m_Header;
|
||||
wadDirEntry *m_Directory;
|
||||
wadDirInfo *m_DirInfo;
|
||||
eWadStatus m_Status;
|
||||
eWadType m_Type;
|
||||
eWadStyle m_Style;
|
||||
|
||||
const wadDirEntry *m_MapStart;
|
||||
const wadDirEntry *m_MapEnd;
|
||||
const wadDirEntry *m_SpriteStart;
|
||||
const wadDirEntry *m_SpriteEnd;
|
||||
const wadDirEntry *m_PatchStart;
|
||||
const wadDirEntry *m_PatchEnd;
|
||||
const wadDirEntry *m_FlatStart;
|
||||
const wadDirEntry *m_FlatEnd;
|
||||
|
||||
void **m_NewData;
|
||||
|
||||
static int sm_NoFilters;
|
||||
static wadFilter **sm_Filter;
|
||||
|
||||
bool EnlargeDirectory ( int holePos, int entries );
|
||||
bool ReduceDirectory ( int holePos, int entries );
|
||||
|
||||
void FindMarkers ();
|
||||
|
||||
bool ReadHeader ( wadHeader * );
|
||||
bool WriteHeader ( FILE *, wadHeader * );
|
||||
|
||||
bool ReadDirEntry ( wadDirEntry * );
|
||||
bool WriteDirEntry ( FILE *, wadDirEntry * );
|
||||
|
||||
bool ReadDirectory ();
|
||||
bool WriteDirectory ( FILE * );
|
||||
|
||||
UINT32 IndexOf ( const wadDirEntry * ) const;
|
||||
|
||||
public:
|
||||
|
||||
WAD ( const char * );
|
||||
~WAD ();
|
||||
|
||||
void SetList ( wadList * );
|
||||
|
||||
static bool IsMap ( const char * );
|
||||
static bool AddFilter ( wadFilter * );
|
||||
|
||||
// Called by wadList::Save
|
||||
void OpenFile ();
|
||||
void CloseFile ();
|
||||
|
||||
bool SaveFile ( const char * = NULL );
|
||||
|
||||
void Type ( eWadType );
|
||||
void Style ( eWadStyle );
|
||||
void Format ( UINT32 );
|
||||
|
||||
const char *Name () const;
|
||||
eWadStatus Status () const;
|
||||
eWadType Type () const;
|
||||
eWadStyle Style () const;
|
||||
UINT32 Format () const;
|
||||
UINT32 FileSize () const;
|
||||
|
||||
bool IsValid () const;
|
||||
bool IsRegistered () const;
|
||||
bool HasChanged () const;
|
||||
bool HasChanged ( const wadDirEntry * ) const;
|
||||
|
||||
eLumpType GetLumpType ( const wadDirEntry * );
|
||||
const char *GetLumpDescription ( eLumpType ) const;
|
||||
const char *GetLumpDescription ( const wadDirEntry * );
|
||||
|
||||
void Seek ( UINT32 );
|
||||
void ReadBytes ( void *, UINT32, UINT32 = 1 );
|
||||
void WriteBytes ( void *, UINT32, UINT32 = 1 );
|
||||
void CopyBytes ( WAD *, UINT32, UINT32 = 1 );
|
||||
|
||||
UINT32 DirSize () const;
|
||||
|
||||
const wadDirEntry *GetDir ( UINT32 ) const;
|
||||
const wadDirEntry *FindDir ( const char *, const wadDirEntry * = NULL, const wadDirEntry * = NULL ) const;
|
||||
|
||||
void *ReadEntry ( const char *, UINT32 *, const wadDirEntry * = NULL, const wadDirEntry * = NULL, bool = false );
|
||||
void *ReadEntry ( const wadDirEntry *, UINT32 *, bool = false );
|
||||
|
||||
bool WriteEntry ( const char *, UINT32, void *, bool, const wadDirEntry * = NULL, const wadDirEntry * = NULL );
|
||||
bool WriteEntry ( const wadDirEntry *, UINT32, void *, bool );
|
||||
|
||||
bool Extract ( const wLumpName *, const char * = NULL ) const;
|
||||
|
||||
bool InsertBefore ( const wLumpName *, const char *, bool, const wadDirEntry * = NULL );
|
||||
bool InsertAfter ( const wLumpName *, const char *, bool, const wadDirEntry * = NULL );
|
||||
|
||||
bool InsertBefore ( const wLumpName *, UINT32, void *, bool, const wadDirEntry * = NULL );
|
||||
bool InsertAfter ( const wLumpName *, UINT32, void *, bool, const wadDirEntry * = NULL );
|
||||
|
||||
bool Remove ( const wLumpName *, const wadDirEntry * = NULL, const wadDirEntry * = NULL );
|
||||
};
|
||||
|
||||
inline void WAD::Format ( UINT32 newFormat ) { * ( UINT32 * ) m_Header.type = newFormat; }
|
||||
inline void WAD::Type ( eWadType newType ) { m_Type = newType; }
|
||||
inline void WAD::Style ( eWadStyle newStyle ) { m_Style = newStyle; }
|
||||
|
||||
inline const char *WAD::Name () const { return m_Name; }
|
||||
inline UINT32 WAD::DirSize () const { return m_Header.dirSize; }
|
||||
inline UINT32 WAD::Format () const { return * ( UINT32 * ) m_Header.type; }
|
||||
inline eWadStatus WAD::Status () const { return m_Status; }
|
||||
inline eWadType WAD::Type () const { return m_Type; }
|
||||
inline eWadStyle WAD::Style () const { return m_Style; }
|
||||
inline bool WAD::IsValid () const { return m_bValid; }
|
||||
inline bool WAD::IsRegistered () const { return m_bRegistered; }
|
||||
|
||||
struct wadListDirEntry {
|
||||
WAD *wad;
|
||||
const wadDirEntry *entry;
|
||||
};
|
||||
|
||||
class wadList {
|
||||
|
||||
struct wadListEntry {
|
||||
WAD *wad;
|
||||
wadListEntry *Next;
|
||||
};
|
||||
|
||||
UINT32 m_DirSize;
|
||||
UINT32 m_MaxSize;
|
||||
wadListDirEntry *m_Directory;
|
||||
eWadType m_Type;
|
||||
eWadStyle m_Style;
|
||||
wadListEntry *m_List;
|
||||
|
||||
UINT32 IndexOf ( const wadListDirEntry * ) const;
|
||||
|
||||
int AddLevel ( UINT32, const wadDirEntry *&, WAD * );
|
||||
void AddDirectory ( WAD *, bool = true );
|
||||
|
||||
public:
|
||||
|
||||
wadList ();
|
||||
~wadList ();
|
||||
|
||||
bool Add ( WAD * );
|
||||
bool Remove ( WAD * );
|
||||
void Clear ();
|
||||
void UpdateDirectory ();
|
||||
|
||||
int wadCount () const;
|
||||
UINT32 FileSize () const;
|
||||
WAD *GetWAD ( int ) const;
|
||||
eWadType Type () const;
|
||||
eWadStyle Style () const;
|
||||
|
||||
bool Save ( const char * = NULL );
|
||||
bool Extract ( const wLumpName *, const char *file = NULL );
|
||||
|
||||
UINT32 DirSize () const;
|
||||
|
||||
const wadListDirEntry *GetDir ( UINT32 ) const;
|
||||
const wadListDirEntry *FindWAD ( const char *, const wadListDirEntry * = NULL, const wadListDirEntry * = NULL ) const;
|
||||
|
||||
bool Contains ( WAD * ) const;
|
||||
bool IsEmpty () const;
|
||||
bool HasChanged () const;
|
||||
};
|
||||
|
||||
inline UINT32 wadList::DirSize () const { return m_DirSize; }
|
||||
inline bool wadList::IsEmpty () const { return ( m_List == NULL ) ? true : false; }
|
||||
inline eWadType wadList::Type () const { return m_Type; }
|
||||
inline eWadStyle wadList::Style () const { return m_Style; }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,22 @@
|
|||
ZenNode v1.2.0
|
||||
==============
|
||||
|
||||
This is directory tree includes the source code necessary to build ZenNode.
|
||||
Since I don't have a lot of time to spend maintaining the code and there
|
||||
haven't been too many changes in the past few years, I've decided to release
|
||||
the source under the GPL license. See the file COPYING for details.
|
||||
|
||||
Several of the files (i.e. those in the DOOM directory) evolved from earlier
|
||||
projects. They contain functionality that is not used in ZenNode and may not
|
||||
have been kept up to date. I think it all works, but I won't make any
|
||||
guarantees.
|
||||
|
||||
There is a makefile included in the ZenNode directory that can be used as is
|
||||
under Linux. To build ZenNode in any other environment, you can use the
|
||||
makefile as a guide. I've built and tested it under Windows using Borland
|
||||
and Microsoft compilers. Older versions have been compiled under OS/2 using
|
||||
Borland. The code should be portable to other compilers, but it has never
|
||||
been tested.
|
||||
|
||||
Enjoy,
|
||||
Marc
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,235 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: ZenNode.hpp
|
||||
// Date: 26-Oct-1994
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Definitions of structures used by the ZenNode routines
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
// 06-??-95 Added LineDef alias list to speed up the process
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef ZENNODE_HPP_
|
||||
#define ZENNODE_HPP_
|
||||
|
||||
#if ! defined ( LEVEL_HPP_ )
|
||||
#include "level.hpp"
|
||||
#endif
|
||||
|
||||
struct sBlockMapOptions {
|
||||
bool Rebuild;
|
||||
bool Compress;
|
||||
};
|
||||
|
||||
struct sNodeOptions {
|
||||
bool Rebuild;
|
||||
int Method;
|
||||
bool Quiet;
|
||||
bool Unique;
|
||||
bool ReduceLineDefs;
|
||||
};
|
||||
|
||||
struct sBlockList {
|
||||
int firstIndex; // Index of 1st blockList element matching this one
|
||||
int offset;
|
||||
int count;
|
||||
int *line;
|
||||
};
|
||||
|
||||
struct sBlockMap {
|
||||
int xOrigin;
|
||||
int yOrigin;
|
||||
int noColumns;
|
||||
int noRows;
|
||||
sBlockList *data;
|
||||
};
|
||||
|
||||
typedef unsigned short BAM;
|
||||
typedef long double REAL; // Must have at least 50 significant bits
|
||||
|
||||
struct sVertex {
|
||||
double x;
|
||||
double y;
|
||||
double l;
|
||||
};
|
||||
|
||||
struct SEG {
|
||||
wSegs Data;
|
||||
const wLineDef *LineDef;
|
||||
int Sector;
|
||||
int Side;
|
||||
int AliasFlip;
|
||||
bool Split;
|
||||
bool DontSplit;
|
||||
bool final;
|
||||
sVertex start;
|
||||
sVertex end;
|
||||
};
|
||||
|
||||
struct sBSPOptions {
|
||||
int algorithm;
|
||||
bool showProgress;
|
||||
bool reduceLineDefs; // global flag for invisible linedefs
|
||||
bool *ignoreLineDef; // linedefs that can be left out
|
||||
bool *dontSplit; // linedefs that can't be split
|
||||
bool *keepUnique; // unique sector requirements
|
||||
};
|
||||
|
||||
struct sScoreInfo {
|
||||
int index;
|
||||
long metric1;
|
||||
long metric2;
|
||||
int invalid;
|
||||
int total;
|
||||
};
|
||||
|
||||
#define sgn(a) ((0<(a))-((a)<0))
|
||||
|
||||
#define BAM90 (( BAM ) 0x4000 ) // BAM: 90ø ( «ã)
|
||||
#define BAM180 (( BAM ) 0x8000 ) // BAM: 180ø ( ñã)
|
||||
#define BAM270 (( BAM ) 0xC000 ) // BAM: 270ø (-«ã)
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
#define SIDE_UNKNOWN -2
|
||||
#define SIDE_LEFT -1
|
||||
#define SIDE_SPLIT 0
|
||||
#define SIDE_RIGHT 1
|
||||
|
||||
#define SIDE_FLIPPED 0xFFFFFFFE
|
||||
#define SIDE_NORMAL 0
|
||||
|
||||
#define LEFT 0
|
||||
#define SPLIT 1
|
||||
#define RIGHT 2
|
||||
|
||||
#define IS_LEFT_RIGHT(s) ( s & 1 )
|
||||
#define FLIP(c,s) ( c ^ s )
|
||||
|
||||
// ---- ZenReject structures to support RMB options ----
|
||||
|
||||
enum REJECT_OPTION_E {
|
||||
OPTION_UNKNOWN,
|
||||
OPTION_MAP_1,
|
||||
OPTION_MAP_2,
|
||||
OPTION_BAND,
|
||||
OPTION_BLIND,
|
||||
OPTION_BLOCK,
|
||||
OPTION_DISTANCE,
|
||||
OPTION_DOOR,
|
||||
OPTION_EXCLUDE,
|
||||
OPTION_GROUP,
|
||||
OPTION_INCLUDE,
|
||||
OPTION_LEFT,
|
||||
OPTION_LENGTH,
|
||||
OPTION_LINE,
|
||||
OPTION_NODOOR,
|
||||
OPTION_NOMAP,
|
||||
OPTION_NOPROCESS,
|
||||
OPTION_ONE,
|
||||
OPTION_PERFECT,
|
||||
OPTION_PREPROCESS,
|
||||
OPTION_PROCESS,
|
||||
OPTION_REPORT,
|
||||
OPTION_RIGHT,
|
||||
OPTION_SAFE,
|
||||
OPTION_TRACE
|
||||
};
|
||||
|
||||
struct sRejectOptionRMB;
|
||||
struct sOptionTableInfo;
|
||||
|
||||
typedef bool (*PARSE_FUNCTION) ( char *, const sOptionTableInfo &, sRejectOptionRMB * );
|
||||
|
||||
struct sOptionTableInfo {
|
||||
const char *Name;
|
||||
const char *Syntax;
|
||||
REJECT_OPTION_E Type;
|
||||
PARSE_FUNCTION ParseFunction;
|
||||
};
|
||||
|
||||
struct sRejectOptionRMB {
|
||||
const sOptionTableInfo *Info;
|
||||
bool Inverted;
|
||||
bool Banded;
|
||||
int Data [2];
|
||||
int *List [2];
|
||||
};
|
||||
|
||||
struct sRejectOptions {
|
||||
bool Rebuild;
|
||||
bool Empty;
|
||||
bool Force;
|
||||
bool FindChildren;
|
||||
bool UseGraphs;
|
||||
bool UseRMB;
|
||||
const sRejectOptionRMB *rmb;
|
||||
};
|
||||
|
||||
bool ParseOptionRMB ( int, const char *, sRejectOptionRMB * );
|
||||
|
||||
// ----- C99 routines from <math.h> Required by ZenNode -----
|
||||
|
||||
#if ( defined ( __GNUC__ ) && ( __GNUC__ < 3 )) || defined ( __INTEL_COMPILER ) || defined ( __BORLANDC__ )
|
||||
|
||||
#if defined ( X86 )
|
||||
|
||||
__inline long lrint ( double flt )
|
||||
{
|
||||
int intgr;
|
||||
|
||||
__asm__ __volatile__ ("fistpl %0" : "=m" (intgr) : "t" (flt) : "st");
|
||||
|
||||
return intgr;
|
||||
}
|
||||
|
||||
#else
|
||||
__inline long lrint ( double flt )
|
||||
{
|
||||
// return ( long ) ( flt + 0.5 * sgn ( flt ));
|
||||
return ( long ) ( flt + 0.5 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined ( _MSC_VER )
|
||||
|
||||
__inline long lrint ( double flt )
|
||||
{
|
||||
int intgr;
|
||||
|
||||
_asm
|
||||
{
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
|
||||
return intgr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern sBlockMap *GenerateBLOCKMAP ( DoomLevel *level );
|
||||
extern int CreateBLOCKMAP ( DoomLevel *level, const sBlockMapOptions &options );
|
||||
extern void CreateNODES ( DoomLevel *level, sBSPOptions *options );
|
||||
extern bool CreateREJECT ( DoomLevel *level, const sRejectOptions &options );
|
||||
|
||||
#endif
|
|
@ -0,0 +1,407 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: ZenRMB.cpp
|
||||
// Date: 30-Oct-2000
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: RMB configuration file support for ZenNode
|
||||
//
|
||||
// Copyright (c) 2000-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "ZenNode.hpp"
|
||||
|
||||
DBG_REGISTER ( __FILE__ );
|
||||
|
||||
bool ParseGeneric ( char *, const sOptionTableInfo &, sRejectOptionRMB * );
|
||||
bool ParseMap ( char *, const sOptionTableInfo &, sRejectOptionRMB * );
|
||||
bool ParseBAND ( char *, const sOptionTableInfo &, sRejectOptionRMB * );
|
||||
bool ParseINVERT ( char *, const sOptionTableInfo &, sRejectOptionRMB * );
|
||||
bool ParseNOPROCESS ( char *, const sOptionTableInfo &, sRejectOptionRMB * );
|
||||
|
||||
sOptionTableInfo ParseTable [] = {
|
||||
{ "BAND", "NNL", OPTION_BAND, ParseBAND },
|
||||
{ "BLIND", "NL", OPTION_BLIND, ParseGeneric },
|
||||
{ "BLOCK", "NN", OPTION_BLOCK, ParseGeneric },
|
||||
{ "DISTANCE", "N", OPTION_DISTANCE, ParseGeneric },
|
||||
{ "DOOR", "N", OPTION_DOOR, ParseGeneric },
|
||||
{ "E*M*", NULL, OPTION_MAP_1, ParseMap },
|
||||
{ "EXCLUDE", "LL", OPTION_EXCLUDE, ParseGeneric },
|
||||
{ "GROUP", "NL", OPTION_GROUP, ParseGeneric },
|
||||
{ "INCLUDE", "LL", OPTION_INCLUDE, ParseGeneric },
|
||||
{ "INVERT", NULL, OPTION_UNKNOWN, ParseINVERT },
|
||||
{ "LEFT", "N", OPTION_LEFT, ParseGeneric },
|
||||
{ "LENGTH", "N", OPTION_LENGTH, ParseGeneric },
|
||||
{ "LINE", "N", OPTION_LINE, ParseGeneric },
|
||||
{ "MAP**", NULL, OPTION_MAP_2, ParseMap },
|
||||
{ "NODOOR", "L", OPTION_NODOOR, ParseGeneric },
|
||||
{ "NOMAP", NULL, OPTION_NOMAP, ParseGeneric },
|
||||
{ "NOPROCESS", NULL, OPTION_NOPROCESS, ParseNOPROCESS },
|
||||
{ "ONE", "NN", OPTION_ONE, ParseGeneric },
|
||||
{ "PERFECT", NULL, OPTION_PERFECT, ParseGeneric },
|
||||
{ "PREPROCESS", "N", OPTION_PREPROCESS, ParseGeneric },
|
||||
{ "PROCESS", "L", OPTION_PROCESS, ParseGeneric },
|
||||
{ "REPORT", "N", OPTION_REPORT, ParseGeneric },
|
||||
{ "RIGHT", "N", OPTION_RIGHT, ParseGeneric },
|
||||
{ "SAFE", "NL", OPTION_SAFE, ParseGeneric },
|
||||
{ "TRACE", "L", OPTION_TRACE, ParseGeneric }
|
||||
};
|
||||
|
||||
static const char *parseText;
|
||||
static int parseLine;
|
||||
static int lastLine;
|
||||
|
||||
const sOptionTableInfo *FindByType ( REJECT_OPTION_E type )
|
||||
{
|
||||
for ( unsigned i = 0; i < SIZE ( ParseTable ); i++ ) {
|
||||
if ( ParseTable [i].Type == type ) return &ParseTable [i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ParseError ( const char *fmt, ... )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseError", true );
|
||||
|
||||
va_list args;
|
||||
va_start ( args, fmt );
|
||||
|
||||
fprintf ( stderr, ( lastLine == parseLine ) ? " " : "Line %3d: ", parseLine );
|
||||
vfprintf ( stderr, fmt, args );
|
||||
fprintf ( stderr, "\n" );
|
||||
|
||||
lastLine = parseLine;
|
||||
}
|
||||
|
||||
int ParseNumber ( char *&text )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseNumber", true );
|
||||
|
||||
if ( ! isdigit ( *text )) throw "expected a number";
|
||||
|
||||
int number = 0;
|
||||
|
||||
while ( isdigit ( *text )) {
|
||||
number *= 10;
|
||||
number += *text++ - '0';
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
int *ParseList ( char *&text, bool strict )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseList", true );
|
||||
|
||||
if (( strict == true ) && ( *text != '(' )) {
|
||||
int *list = new int [ 2 ];
|
||||
list [0] = ParseNumber ( text );
|
||||
list [1] = -1;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool close = false;
|
||||
|
||||
if ( *text == '(' ) {
|
||||
close = true;
|
||||
text++;
|
||||
}
|
||||
|
||||
while ( isspace ( *text )) text++;
|
||||
|
||||
if ( *text == '\0' ) throw "Invalid list";
|
||||
|
||||
int count = 0;
|
||||
|
||||
char *ptr = text;
|
||||
if ( isdigit ( *ptr )) {
|
||||
while (( *ptr != '\0' ) && ( *ptr != ')' )) {
|
||||
if ( ! isdigit ( *ptr )) throw "Invalid list";
|
||||
while ( isdigit ( *ptr )) ptr++;
|
||||
if ( *ptr == ',' ) ptr++;
|
||||
while ( isspace ( *ptr )) ptr++;
|
||||
count++;
|
||||
}
|
||||
/* Is this valid???
|
||||
} else {
|
||||
if ( strncmp ( ptr, "ALL", 3 ) != 0 ) throw "Invalid list";
|
||||
ptr += 3;
|
||||
while ( isspace ( *ptr )) ptr++;
|
||||
*/
|
||||
}
|
||||
|
||||
if (( close == true ) && ( *ptr != ')' )) throw "List must end with a ')'";
|
||||
|
||||
int *list = new int [ count + 1 ];
|
||||
for ( int i = 0; i < count; i++ ) {
|
||||
list [i] = atoi ( text );
|
||||
while ( isdigit ( *text )) text++;
|
||||
if ( *text == ',' ) text++;
|
||||
while ( isspace ( *text )) text++;
|
||||
}
|
||||
|
||||
if ( close == true ) text++;
|
||||
|
||||
list [count] = -1;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
bool ParseGeneric ( char *text, const sOptionTableInfo &info, sRejectOptionRMB *option )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseGeneric", true );
|
||||
|
||||
int dataIndex = 0;
|
||||
int listIndex = 0;
|
||||
|
||||
const char *syntax = info.Syntax;
|
||||
|
||||
try {
|
||||
|
||||
if ( syntax != NULL ) while ( *syntax ) {
|
||||
while ( isspace ( *text )) text++;
|
||||
switch ( *syntax++ ) {
|
||||
case 'N' :
|
||||
option->Data [dataIndex++] = ParseNumber ( text );
|
||||
break;
|
||||
case 'L' :
|
||||
option->List [listIndex++] = ParseList ( text, ( *syntax != '\0' ) ? true : false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while ( isspace ( *text )) text++;
|
||||
if (( *text != '\0' ) && ( *text != '#' )) throw "unexpected characters after command";
|
||||
|
||||
option->Info = &info;
|
||||
}
|
||||
|
||||
catch ( const char *message ) {
|
||||
ParseError ( "Syntax error - %s.", message );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseMap ( char *text, const sOptionTableInfo &info, sRejectOptionRMB *option )
|
||||
{
|
||||
option->Info = &info;
|
||||
|
||||
while ( ! isdigit ( *text )) text--;
|
||||
|
||||
switch ( info.Type ) {
|
||||
case OPTION_MAP_1 :
|
||||
option->Data [0] = text [-2] - '0';
|
||||
option->Data [1] = text [0] - '0';
|
||||
break;
|
||||
case OPTION_MAP_2 :
|
||||
option->Data [0] = ( text [-1] - '0' ) * 10 + ( text [0] - '0' );
|
||||
break;
|
||||
default :
|
||||
ParseError ( "Unable to parse map name" );
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseBAND ( char *text, const sOptionTableInfo &info, sRejectOptionRMB *option )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseBAND", true );
|
||||
|
||||
REJECT_OPTION_E type = OPTION_UNKNOWN;
|
||||
|
||||
while ( isspace ( *text )) text++;
|
||||
|
||||
if ( strncmp ( text, "BLIND", 5 ) == 0 ) {
|
||||
type = OPTION_BLIND;
|
||||
text += 5;
|
||||
} else if ( strncmp ( text, "SAFE", 5 ) == 0 ) {
|
||||
type = OPTION_SAFE;
|
||||
text += 4;
|
||||
} else {
|
||||
goto bad_option;
|
||||
}
|
||||
|
||||
if ( isspace ( *text )) {
|
||||
bool retVal = ParseGeneric ( text, info, option );
|
||||
option->Banded = true;
|
||||
option->Info = FindByType ( type );
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bad_option:
|
||||
|
||||
ParseError ( "Invalid BAND option." );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParseINVERT ( char *text, const sOptionTableInfo &info, sRejectOptionRMB *option )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseINVERT", true );
|
||||
|
||||
if ( ParseOptionRMB ( -1, text, option ) == true ) {
|
||||
switch ( option->Info->Type ) {
|
||||
case OPTION_BAND :
|
||||
case OPTION_BLIND :
|
||||
case OPTION_SAFE :
|
||||
option->Inverted = true;
|
||||
break;
|
||||
default :
|
||||
ParseError ( "Invalid %s option '%s'.", info.Name, text );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
ParseError ( "Unable to process %s effect.", info.Name );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParseNOPROCESS ( char *text, const sOptionTableInfo &info, sRejectOptionRMB *option )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseNOPROCESS", true );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParseOptionRMB ( int lineNumber, const char *lineText, sRejectOptionRMB *option )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ParseOptionRMB", true );
|
||||
|
||||
ASSERT ( lineText != NULL );
|
||||
ASSERT ( option != NULL );
|
||||
|
||||
if ( lineNumber > 0 ) {
|
||||
parseLine = lineNumber;
|
||||
parseText = lineText;
|
||||
}
|
||||
|
||||
memset ( option, 0, sizeof ( sRejectOptionRMB ));
|
||||
|
||||
const char *srcText = lineText;
|
||||
while (( *srcText != '\0' ) && ( isspace ( *srcText ))) srcText++;
|
||||
|
||||
if (( *srcText == '#' ) || ( *srcText == '\0' )) return false;
|
||||
|
||||
size_t length = strlen ( srcText );
|
||||
char *buffer = new char [ length + 1 ];
|
||||
for ( size_t i = 0; i < length; i++ ) {
|
||||
buffer [i] = toupper ( srcText [i] );
|
||||
if (( buffer [i] == '\r' ) || ( buffer [i] == '\n' )) length = i;
|
||||
}
|
||||
buffer [length] = '\0';
|
||||
|
||||
char *start = buffer;
|
||||
char *end = buffer;
|
||||
while (( *end != '\0' ) && ( ! isspace ( *end ))) end++;
|
||||
|
||||
bool retVal = false;
|
||||
|
||||
if ( start != end ) {
|
||||
|
||||
for ( unsigned i = 0; i < SIZE ( ParseTable ); i++ ) {
|
||||
char *src = start;
|
||||
const char *tgt = ParseTable [i].Name;
|
||||
while (( src != end ) && ( *tgt != '\0' )) {
|
||||
if ( *src != *tgt ) {
|
||||
if ( *tgt != '*' ) goto next;
|
||||
if ( ! isdigit ( *src )) goto next;
|
||||
}
|
||||
src++;
|
||||
tgt++;
|
||||
}
|
||||
if (( i + 1 < SIZE ( ParseTable )) && ( strncmp ( buffer, ParseTable [i+1].Name, src - buffer ) == 0 )) {
|
||||
ParseError ( "'%*.*s' is not a unique identifier.", end - buffer, end - buffer, buffer );
|
||||
goto done;
|
||||
}
|
||||
while ( isspace ( *end )) end++;
|
||||
retVal = ParseTable [i].ParseFunction ( end, ParseTable [i], option );
|
||||
goto done;
|
||||
next:
|
||||
;
|
||||
}
|
||||
|
||||
ParseError ( "Unrecognized effect '%*.*s'.", end - buffer, end - buffer, buffer );
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void PrintOption ( FILE *file, sRejectOptionRMB *option )
|
||||
{
|
||||
const sOptionTableInfo *info = option->Info;
|
||||
const char *syntax = info->Syntax;
|
||||
|
||||
if ( option->Inverted ) fprintf ( file, "INVERT " );
|
||||
if ( option->Banded ) {
|
||||
syntax = "NNL";
|
||||
fprintf ( file, "BAND " );
|
||||
}
|
||||
|
||||
switch ( info->Type ) {
|
||||
case OPTION_MAP_1 :
|
||||
fprintf ( file, "E%dM%d", option->Data [0], option->Data [1] );
|
||||
break;
|
||||
case OPTION_MAP_2 :
|
||||
fprintf ( file, "MAP%02d", option->Data [0] );
|
||||
break;
|
||||
default :
|
||||
fprintf ( file, "%s", info->Name );
|
||||
break;
|
||||
}
|
||||
|
||||
int dataIndex = 0;
|
||||
int listIndex = 0;
|
||||
|
||||
if ( syntax != NULL ) while ( *syntax ) {
|
||||
switch ( *syntax++ ) {
|
||||
case 'N' :
|
||||
fprintf ( file, " %d", option->Data [dataIndex++] );
|
||||
break;
|
||||
case 'L' :
|
||||
int *list;
|
||||
fprintf ( file, " (" );
|
||||
list = option->List [listIndex++];
|
||||
while ( *list != -1 ) fprintf ( file, " %d", *list++ );
|
||||
fprintf ( file, " )" );
|
||||
break;
|
||||
default :
|
||||
fprintf ( stderr, "Internal error: Invalid syntax\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf ( file, "\n" );
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
void DotGraph ( sGraph *graph )
|
||||
{
|
||||
int maxMetric = 0;
|
||||
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) {
|
||||
if ( graph->sector [x]->metric > maxMetric ) maxMetric = graph->sector [x]->metric;
|
||||
}
|
||||
|
||||
fprintf ( stderr, "digraph g {\n" );
|
||||
fprintf ( stderr, "\tsize = \"12,12\";\n" );
|
||||
fprintf ( stderr, "\tnode [shape=record];\n" );
|
||||
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) {
|
||||
sSector *sec1 = graph->sector [x];
|
||||
if ( sec1->graphParent != NULL ) fprintf ( stderr, "\t%d -> %d%s;\n", sec1->graphParent->index, sec1->index, ( sec1->loDFS < sec1->indexDFS ) ? " [color=green]" : "" );
|
||||
for ( int i = 0; i < sec1->noNeighbors; i++ ) {
|
||||
sSector *sec2 = sec1->neighbor [i];
|
||||
if ( sec1->graphParent == sec2 ) continue;
|
||||
if (( sec2->graphParent != sec1 ) && ( sec1->index > sec2->index )) fprintf ( stderr, "\t%d -> %d [color=red];\n", sec1->index, sec2->index );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) {
|
||||
sSector *sec = graph->sector [x];
|
||||
fprintf ( stderr, "\t%d [label=\"%d | { %d | %d | %d } | %d\"];\n", sec->index, sec->loDFS, sec->index, sec->indexDFS, sec->metric, sec->hiDFS );
|
||||
}
|
||||
|
||||
fprintf ( stderr, "}\n" );
|
||||
|
||||
}
|
||||
|
||||
void NeatoGraph ( sGraph *graph )
|
||||
{
|
||||
int maxMetric = 0;
|
||||
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) {
|
||||
if ( graph->sector [x]->metric > maxMetric ) maxMetric = graph->sector [x]->metric;
|
||||
}
|
||||
|
||||
fprintf ( stderr, "graph g {\n" );
|
||||
fprintf ( stderr, "\tsize = \"12,12\";\n" );
|
||||
fprintf ( stderr, "\tnode [style=filled,fontcolor=white];\n" );
|
||||
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) {
|
||||
sSector *sec1 = graph->sector [x];
|
||||
for ( int i = 0; i < sec1->noNeighbors; i++ ) {
|
||||
sSector *sec2 = sec1->neighbor [i];
|
||||
if ( sec1->index < sec2->index ) fprintf ( stderr, "\t%d -- %d;\n", sec1->index, sec2->index );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) {
|
||||
sSector *sec = graph->sector [x];
|
||||
int color = ( maxMetric != 0 ) ? ( int ) ( 0xFF * sqrt (( double ) sec->metric / ( double ) maxMetric )) : 0;
|
||||
fprintf ( stderr, "\t%d [color=\"#%02X%02X%02X\"%s];\n", sec->index, color, 0, 0, ( color > 0x80 ) ? ",fontcolor=black" : "" );
|
||||
}
|
||||
|
||||
fprintf ( stderr, "}\n" );
|
||||
|
||||
}
|
||||
|
||||
void DumpGraph ( sGraph *graph )
|
||||
{
|
||||
fprintf ( stderr, "%08X:", graph );
|
||||
for ( int x = 0; x < graph->noSectors; x++ ) fprintf ( stderr, " %d", graph->sector [x]->index );
|
||||
fprintf ( stderr, "\n" );
|
||||
}
|
||||
|
||||
void PrintGraph ( sGraph *graph )
|
||||
{
|
||||
fprintf ( stderr, "%08X:\n", graph );
|
||||
|
||||
int artCount = 0, childCount = 0;
|
||||
|
||||
for ( int i = 0; i < graph->noSectors; i++ ) {
|
||||
sSector *sec = graph->sector [i];
|
||||
if ( sec->isArticulation == true ) artCount++;
|
||||
if ( sec->noChildren > 0 ) childCount++;
|
||||
fprintf ( stderr, " %4d(%4d-%4d,%4d,%7d)%s %4d %3d/%3d", sec->index, sec->loDFS, sec->indexDFS, sec->hiDFS, sec->metric, sec->isArticulation ? "*" : " ", sec->noChildren, sec->noActiveNeighbors, sec->noNeighbors );
|
||||
if ( sec->noActiveNeighbors == 2 ) {
|
||||
sSector *sec1 = sec->neighbor [0];
|
||||
sSector *sec2 = sec->neighbor [1];
|
||||
if (( sec1->isArticulation == true ) && ( sec2->isArticulation == true )) {
|
||||
fprintf ( stderr, " -step-" );
|
||||
}
|
||||
}
|
||||
while ( sec->parent != NULL ) {
|
||||
sec = sec->parent;
|
||||
fprintf ( stderr, " %4d%s", sec->index, sec->isArticulation ? "*" : "" );
|
||||
}
|
||||
fprintf ( stderr, "\n" );
|
||||
}
|
||||
fprintf ( stderr, " %4d %3d\n", artCount, childCount );
|
||||
|
||||
fprintf ( stderr, "\n" );
|
||||
}
|
||||
|
||||
int CompareREJECT ( UCHAR *srcPtr, UCHAR *tgtPtr, int noSectors )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "CompareREJECT", true );
|
||||
|
||||
bool match = true;
|
||||
|
||||
int **vis2hid = new int * [ noSectors ];
|
||||
int **hid2vis = new int * [ noSectors ];
|
||||
|
||||
int *v2hCount = new int [ noSectors ];
|
||||
int *h2vCount = new int [ noSectors ];
|
||||
|
||||
int bits = 8;
|
||||
int srcVal = *srcPtr++;
|
||||
int tgtVal = *tgtPtr++;
|
||||
int dif = srcVal ^ tgtVal;
|
||||
for ( int i = 0; i < noSectors; i++ ) {
|
||||
vis2hid [i] = new int [ noSectors ];
|
||||
hid2vis [i] = new int [ noSectors ];
|
||||
memset ( vis2hid [i], 0, noSectors * sizeof ( int ));
|
||||
memset ( hid2vis [i], 0, noSectors * sizeof ( int ));
|
||||
v2hCount [i] = 0;
|
||||
h2vCount [i] = 0;
|
||||
for ( int j = 0; j < noSectors; j++ ) {
|
||||
if ( dif & 1 ) {
|
||||
if ( srcVal & 1 ) {
|
||||
hid2vis [i][h2vCount [i]++] = j;
|
||||
} else {
|
||||
vis2hid [i][v2hCount [i]++] = j;
|
||||
}
|
||||
match = false;
|
||||
}
|
||||
if ( --bits == 0 ) {
|
||||
bits = 8;
|
||||
srcVal = *srcPtr++;
|
||||
tgtVal = *tgtPtr++;
|
||||
dif = srcVal ^ tgtVal;
|
||||
} else {
|
||||
srcVal >>= 1;
|
||||
tgtVal >>= 1;
|
||||
dif >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
for ( int i = 0; i < noSectors; i++ ) {
|
||||
if (( v2hCount [i] == 0 ) && ( h2vCount [i] == 0 )) continue;
|
||||
bool v2h = false;
|
||||
for ( int j = 0; j < v2hCount [i]; j++ ) {
|
||||
int index = vis2hid [i][j];
|
||||
if (( v2hCount [i] > v2hCount [index] ) ||
|
||||
(( v2hCount [i] == v2hCount [index] ) && ( i > index ))) {
|
||||
v2h = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool h2v = false;
|
||||
for ( int j = 0; j < h2vCount [i]; j++ ) {
|
||||
int index = hid2vis [i][j];
|
||||
if (( h2vCount [i] > h2vCount [index] ) ||
|
||||
(( h2vCount [i] == h2vCount [index] ) && ( i > index ))) {
|
||||
h2v = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( v2h == true ) {
|
||||
if ( first == false ) printf ( " " );
|
||||
printf ( "vis->hid %5d:", i );
|
||||
for ( int j = 0; j < v2hCount [i]; j++ ) {
|
||||
printf ( " %d", vis2hid [i][j] );
|
||||
}
|
||||
printf ( "\n" );
|
||||
first = false;
|
||||
}
|
||||
if ( h2v == true ) {
|
||||
if ( first == false ) printf ( " " );
|
||||
printf ( "hid->vis %5d:", i );
|
||||
for ( int j = 0; j < h2vCount [i]; j++ ) {
|
||||
printf ( " %d", hid2vis [i][j] );
|
||||
}
|
||||
printf ( "\n" );
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( match == true ) printf ( "Perfect Match\n" );
|
||||
|
||||
for ( int i = 0; i < noSectors; i++ ) {
|
||||
delete [] vis2hid [i];
|
||||
delete [] hid2vis [i];
|
||||
}
|
||||
|
||||
delete [] vis2hid;
|
||||
delete [] hid2vis;
|
||||
|
||||
delete [] v2hCount;
|
||||
delete [] h2vCount;
|
||||
|
||||
return match ? 0 : 1;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,258 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: blockmap.cpp
|
||||
// Date: 14-Jul-1995
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: This module contains the logic for the BLOCKMAP builder.
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "common.hpp"
|
||||
#include "level.hpp"
|
||||
#include "ZenNode.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
void AddLineDef ( sBlockList *block, int line )
|
||||
{
|
||||
if (( block->count % 16 ) == 0 ) {
|
||||
int size = ( block->count + 16 ) * sizeof ( int );
|
||||
block->line = ( int * ) realloc ( block->line, size );
|
||||
}
|
||||
block->line [ block->count++ ] = line;
|
||||
}
|
||||
|
||||
sBlockMap *GenerateBLOCKMAP ( DoomLevel *level )
|
||||
{
|
||||
Status ( "Creating BLOCKMAP ... " );
|
||||
|
||||
const wVertex *vertex = level->GetVertices ();
|
||||
const wLineDef *lineDef = level->GetLineDefs ();
|
||||
|
||||
int xLeft, xRight, yTop, yBottom;
|
||||
xRight = xLeft = vertex [0].x;
|
||||
yTop = yBottom = vertex [0].y;
|
||||
|
||||
for ( int i = 1; i < level->VertexCount (); i++ ) {
|
||||
if ( vertex [i].x < xLeft ) xLeft = vertex [i].x;
|
||||
if ( vertex [i].x > xRight ) xRight = vertex [i].x;
|
||||
if ( vertex [i].y < yBottom ) yBottom = vertex [i].y;
|
||||
if ( vertex [i].y > yTop ) yTop = vertex [i].y;
|
||||
}
|
||||
|
||||
xLeft -= 8; xRight += 8;
|
||||
yBottom -= 8; yTop += 8;
|
||||
|
||||
int noCols = ( xRight - xLeft ) / 128 + 1;
|
||||
int noRows = ( yTop - yBottom ) / 128 + 1;
|
||||
int totalSize = noCols * noRows;
|
||||
|
||||
sBlockList *blockList = new sBlockList [ totalSize ];
|
||||
for ( int i = 0; i < totalSize; i++ ) {
|
||||
blockList [i].firstIndex = i;
|
||||
blockList [i].offset = 0;
|
||||
blockList [i].count = 0;
|
||||
blockList [i].line = NULL;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < level->LineDefCount (); i++ ) {
|
||||
|
||||
const wVertex *vertS = &vertex [ lineDef [i].start ];
|
||||
const wVertex *vertE = &vertex [ lineDef [i].end ];
|
||||
|
||||
long x0 = vertS->x - xLeft;
|
||||
long y0 = vertS->y - yBottom;
|
||||
long x1 = vertE->x - xLeft;
|
||||
long y1 = vertE->y - yBottom;
|
||||
|
||||
int startX = x0 / 128, startY = y0 / 128;
|
||||
int endX = x1 / 128, endY = y1 / 128;
|
||||
|
||||
int index = startX + startY * noCols;
|
||||
|
||||
if ( startX == endX ) {
|
||||
AddLineDef ( &blockList [ index ], i );
|
||||
if ( startY != endY ) { // vertical line
|
||||
int dy = (( endY - startY ) > 0 ) ? 1 : -1;
|
||||
do {
|
||||
startY += dy;
|
||||
index += dy * noCols;
|
||||
AddLineDef ( &blockList [ index ], i );
|
||||
} while ( startY != endY );
|
||||
}
|
||||
} else {
|
||||
if ( startY == endY ) { // horizontal line
|
||||
AddLineDef ( &blockList [ index ], i );
|
||||
int dx = (( endX - startX ) > 0 ) ? 1 : -1;
|
||||
do {
|
||||
startX += dx;
|
||||
index += dx;
|
||||
AddLineDef ( &blockList [ index ], i );
|
||||
} while ( startX != endX );
|
||||
} else { // diagonal line
|
||||
|
||||
int dx = ( x1 - x0 );
|
||||
int dy = ( y1 - y0 );
|
||||
|
||||
int sx = ( dx < 0 ) ? -1 : 1;
|
||||
int sy = ( dy < 0 ) ? -1 : 1;
|
||||
|
||||
x1 *= dy;
|
||||
int nextX = x0 * dy;
|
||||
int deltaX = ( startY * 128 + 64 * ( 1 + sy ) - y0 ) * dx;
|
||||
|
||||
bool done = false;
|
||||
|
||||
do {
|
||||
int thisX = nextX;
|
||||
nextX += deltaX;
|
||||
if (( sx * sy * nextX ) >= ( sx * sy * x1 )) nextX = x1, done = true;
|
||||
|
||||
int lastIndex = index + nextX / dy / 128 - thisX / dy / 128;
|
||||
|
||||
AddLineDef ( &blockList [ index ], i );
|
||||
while ( index != lastIndex ) {
|
||||
index += sx;
|
||||
AddLineDef ( &blockList [ index ], i );
|
||||
}
|
||||
|
||||
index += sy * noCols;
|
||||
deltaX = ( 128 * dx ) * sy;
|
||||
|
||||
} while ( ! done );
|
||||
|
||||
int lastIndex = endX + endY * noCols;
|
||||
if ( index != lastIndex + sy * noCols ) {
|
||||
AddLineDef ( &blockList [ lastIndex ], i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sBlockMap *blockMap = new sBlockMap;
|
||||
blockMap->xOrigin = xLeft;
|
||||
blockMap->yOrigin = yBottom;
|
||||
blockMap->noColumns = noCols;
|
||||
blockMap->noRows = noRows;
|
||||
blockMap->data = blockList;
|
||||
|
||||
return blockMap;
|
||||
}
|
||||
|
||||
int CreateBLOCKMAP ( DoomLevel *level, const sBlockMapOptions &options )
|
||||
{
|
||||
// Generate the data
|
||||
sBlockMap *blockMap = GenerateBLOCKMAP ( level );
|
||||
|
||||
Status ( "Packing BLOCKMAP ... " );
|
||||
|
||||
sBlockList *blockList = blockMap->data;
|
||||
|
||||
// Count unique blockList elements
|
||||
int totalSize = blockMap->noColumns * blockMap->noRows;
|
||||
int blockListSize = 0, savings = 0;
|
||||
int zeroIndex = -1;
|
||||
for ( int i = 0; i < totalSize; i++ ) {
|
||||
if ( options.Compress ) {
|
||||
if ( blockList [i].count == 0 ) {
|
||||
if ( zeroIndex != -1 ) {
|
||||
blockList [i].firstIndex = zeroIndex;
|
||||
savings += 0 + 2;
|
||||
continue;
|
||||
}
|
||||
zeroIndex = i;
|
||||
} else {
|
||||
// Only go back to the beginning of the previous row
|
||||
int rowStart = ( i / blockMap->noColumns ) * blockMap->noColumns;
|
||||
int lastStart = rowStart ? rowStart - blockMap->noColumns : 0;
|
||||
int index = i - 1;
|
||||
while ( index >= lastStart ) {
|
||||
int count = blockList[i].count;
|
||||
if (( blockList[index].count == count ) &&
|
||||
( memcmp ( blockList[i].line, blockList[index].line, count * sizeof ( int )) == 0 )) {
|
||||
blockList [i].firstIndex = index;
|
||||
savings += count + 2;
|
||||
break;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
if ( index >= lastStart ) continue;
|
||||
}
|
||||
}
|
||||
blockList [i].firstIndex = i;
|
||||
blockListSize += 2 + blockList [i].count;
|
||||
}
|
||||
|
||||
Status ( "Saving BLOCKMAP ... " );
|
||||
|
||||
int blockSize = sizeof ( wBlockMap ) +
|
||||
totalSize * sizeof ( INT16 ) +
|
||||
blockListSize * sizeof ( INT16 );
|
||||
char *start = new char [ blockSize ];
|
||||
wBlockMap *map = ( wBlockMap * ) start;
|
||||
map->xOrigin = ( INT16 ) blockMap->xOrigin;
|
||||
map->yOrigin = ( INT16 ) blockMap->yOrigin;
|
||||
map->noColumns = ( UINT16 ) blockMap->noColumns;
|
||||
map->noRows = ( UINT16 ) blockMap->noRows;
|
||||
|
||||
// Fill in data & offsets
|
||||
UINT16 *offset = ( UINT16 * ) ( map + 1 );
|
||||
UINT16 *data = offset + totalSize;
|
||||
for ( int i = 0; i < totalSize; i++ ) {
|
||||
sBlockList *block = &blockList [i];
|
||||
if ( block->firstIndex == i ) {
|
||||
block->offset = data - ( UINT16 * ) start;
|
||||
*data++ = 0;
|
||||
for ( int x = 0; x < block->count; x++ ) {
|
||||
*data++ = ( UINT16 ) block->line [x];
|
||||
}
|
||||
*data++ = ( UINT16 ) -1;
|
||||
} else {
|
||||
block->offset = blockList [ block->firstIndex ].offset;
|
||||
}
|
||||
}
|
||||
|
||||
bool errors = false;
|
||||
|
||||
for ( int i = 0; i < totalSize; i++ ) {
|
||||
if ( blockList [i].offset > 0xFFFF ) {
|
||||
errors = true;
|
||||
}
|
||||
offset [i] = ( UINT16 ) blockList [i].offset;
|
||||
if ( blockList [i].line ) free ( blockList [i].line );
|
||||
}
|
||||
|
||||
delete [] blockList;
|
||||
delete blockMap;
|
||||
|
||||
if ( errors == true ) {
|
||||
delete [] start;
|
||||
return -1;
|
||||
}
|
||||
|
||||
level->NewBlockMap ( blockSize, map );
|
||||
|
||||
return savings * sizeof ( INT16 );
|
||||
}
|
|
@ -0,0 +1,462 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: bspdiff.cpp
|
||||
// Date: 27-Oct-2000
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Compares two BSP structures and report any differences
|
||||
//
|
||||
// Copyright (c) 2000-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined ( __OS2__ )
|
||||
#define INCL_DOS
|
||||
#define INCL_SUB
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include <os2.h>
|
||||
#elif defined ( __WIN32__ )
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include <windows.h>
|
||||
#include <wincon.h>
|
||||
#elif defined ( __GNUC__ )
|
||||
#else
|
||||
#error This program must be compiled as a 32-bit app.
|
||||
#endif
|
||||
|
||||
#include "common.hpp"
|
||||
#include "wad.hpp"
|
||||
#include "level.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define MAX_LEVELS 50
|
||||
|
||||
#define UNSUPPORTED_FEATURE -1
|
||||
#define UNRECOGNIZED_PARAMETER -2
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#define cprintf printf
|
||||
|
||||
extern char *strupr ( char *ptr );
|
||||
extern int getch ();
|
||||
extern bool kbhit ();
|
||||
|
||||
#endif
|
||||
|
||||
int GCD ( int A, int B )
|
||||
{
|
||||
if ( A < 0 ) A = -A; else if ( A == 0 ) return 1;
|
||||
if ( B < 0 ) B = -B; else if ( B == 0 ) return 1;
|
||||
|
||||
unsigned twos = 0;
|
||||
while ((( A | B ) & 1 ) == 0 ) {
|
||||
twos++;
|
||||
A >>= 1;
|
||||
B >>= 1;
|
||||
}
|
||||
|
||||
while (( A & 1 ) == 0 ) A >>= 1; // remove other powers of 2
|
||||
while (( B & 1 ) == 0 ) B >>= 1; // remove other powers of 2
|
||||
|
||||
// A and B both odd at this point!
|
||||
while ( A != B ) {
|
||||
while ( A > B ) {
|
||||
A -= B; // subtractracting smaller odd number
|
||||
// from larger odd number. ( A now even )
|
||||
while (( A & 1 ) == 0 ) A >>= 1; // remove powers of 2
|
||||
}
|
||||
while ( B > A ) {
|
||||
B -= A; // subtractracting smaller odd number
|
||||
// from larger odd number. ( B now even )
|
||||
while (( B & 1 ) == 0 ) B >>= 1; // remove powers of 2
|
||||
}
|
||||
}
|
||||
|
||||
return ( A << twos ); // reapply original powers of two
|
||||
}
|
||||
|
||||
void printHelp ()
|
||||
{
|
||||
fprintf ( stderr, "Usage: nodediff {-options} filename1[.wad] filename2[.wad] [level{+level}]\n" );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " -x+ turn on option -x- turn off option %c = default\n", DEFAULT_CHAR );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " level - ExMy for DOOM / Heretic\n" );
|
||||
fprintf ( stderr, " MAPxx for DOOM II / HEXEN\n" );
|
||||
}
|
||||
|
||||
int parseArgs ( int index, const char *argv[] )
|
||||
{
|
||||
bool errors = false;
|
||||
while ( argv [ index ] ) {
|
||||
|
||||
if ( argv [index][0] != '/' ) break;
|
||||
|
||||
index++;
|
||||
}
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
return index;
|
||||
}
|
||||
|
||||
int getLevels ( int argIndex, const char *argv[], char names [][MAX_LUMP_NAME], wadList *list )
|
||||
{
|
||||
int index = 0, errors = 0;
|
||||
|
||||
char buffer [128];
|
||||
buffer [0] = '\0';
|
||||
if ( argv [argIndex] ) {
|
||||
strcpy ( buffer, argv [argIndex] );
|
||||
strupr ( buffer );
|
||||
}
|
||||
char *ptr = strtok ( buffer, "+" );
|
||||
|
||||
// See if the user requested specific levels
|
||||
if ( WAD::IsMap ( ptr )) {
|
||||
argIndex++;
|
||||
while ( ptr ) {
|
||||
if ( WAD::IsMap ( ptr ))
|
||||
if ( list->FindWAD ( ptr ))
|
||||
strcpy ( names [index++], ptr );
|
||||
else
|
||||
fprintf ( stderr, " Could not find %s\n", ptr, errors++ );
|
||||
else
|
||||
fprintf ( stderr, " %s is not a valid name for a level\n", ptr, errors++ );
|
||||
ptr = strtok ( NULL, "+" );
|
||||
}
|
||||
} else {
|
||||
int size = list->DirSize ();
|
||||
const wadListDirEntry *dir = list->GetDir ( 0 );
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
if ( dir->wad->IsMap ( dir->entry->name )) {
|
||||
if ( index == MAX_LEVELS )
|
||||
fprintf ( stderr, "ERROR: Too many levels in WAD - ignoring %s!\n", dir->entry->name, errors++ );
|
||||
else
|
||||
memcpy ( names [index++], dir->entry->name, MAX_LUMP_NAME );
|
||||
}
|
||||
dir++;
|
||||
}
|
||||
}
|
||||
memset ( names [index], 0, MAX_LUMP_NAME );
|
||||
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
return argIndex;
|
||||
}
|
||||
|
||||
void EnsureExtension ( char *fileName, const char *ext )
|
||||
{
|
||||
size_t length = strlen ( fileName );
|
||||
char *ptr = strrchr ( fileName, '.' );
|
||||
if (( ptr && strchr ( ptr, '\\' )) ||
|
||||
( ! ptr && stricmp ( &fileName[length-4], ext )))
|
||||
strcat ( fileName, ext );
|
||||
}
|
||||
|
||||
const char *TypeName ( eWadType type )
|
||||
{
|
||||
switch ( type ) {
|
||||
case wt_DOOM : return "DOOM";
|
||||
case wt_DOOM2 : return "DOOM2";
|
||||
case wt_HERETIC : return "Heretic";
|
||||
case wt_HEXEN : return "Hexen";
|
||||
default : break;
|
||||
}
|
||||
return "<Unknown>";
|
||||
}
|
||||
|
||||
wadList *getInputFiles ( const char *cmdLine, char *wadFileName )
|
||||
{
|
||||
char *listNames = wadFileName;
|
||||
wadList *myList = new wadList;
|
||||
|
||||
if ( cmdLine == NULL ) return myList;
|
||||
|
||||
char temp [ 256 ];
|
||||
strcpy ( temp, cmdLine );
|
||||
char *ptr = strtok ( temp, "+" );
|
||||
|
||||
int errors = 0;
|
||||
while ( ptr && *ptr ) {
|
||||
char wadName [ 256 ];
|
||||
strcpy ( wadName, ptr );
|
||||
EnsureExtension ( wadName, ".wad" );
|
||||
|
||||
WAD *wad = new WAD ( wadName );
|
||||
if ( wad->Status () != ws_OK ) {
|
||||
const char *msg;
|
||||
switch ( wad->Status ()) {
|
||||
case ws_INVALID_FILE : msg = "The file %s does not exist\n"; break;
|
||||
case ws_CANT_READ : msg = "Can't open the file %s for read access\n"; break;
|
||||
case ws_INVALID_WAD : msg = "%s is not a valid WAD file\n"; break;
|
||||
default : msg = "** Unexpected Error opening %s **\n"; break;
|
||||
}
|
||||
fprintf ( stderr, msg, wadName );
|
||||
delete wad;
|
||||
} else {
|
||||
if ( ! myList->IsEmpty ()) {
|
||||
cprintf ( "Merging: %s with %s\r\n", wadName, listNames );
|
||||
*wadFileName++ = '+';
|
||||
}
|
||||
if ( myList->Add ( wad ) == false ) {
|
||||
errors++;
|
||||
if ( myList->Type () != wt_UNKNOWN )
|
||||
fprintf ( stderr, "ERROR: %s is not a %s PWAD.\n", wadName, TypeName ( myList->Type ()));
|
||||
else
|
||||
fprintf ( stderr, "ERROR: %s is not the same type.\n", wadName );
|
||||
delete wad;
|
||||
} else {
|
||||
char *end = wadName + strlen ( wadName ) - 1;
|
||||
while (( end > wadName ) && ( *end != '\\' )) end--;
|
||||
if ( *end == '\\' ) end++;
|
||||
wadFileName += sprintf ( wadFileName, "%s", end );
|
||||
}
|
||||
}
|
||||
ptr = strtok ( NULL, "+" );
|
||||
}
|
||||
if ( wadFileName [-1] == '+' ) wadFileName [-1] = '\0';
|
||||
if ( myList->wadCount () > 1 ) cprintf ( "\r\n" );
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return myList;
|
||||
}
|
||||
|
||||
template <class T> inline T sgn ( T val ) { return ( val > 0 ) ? 1 : ( val < 0 ) ? -1 : 0; }
|
||||
|
||||
void NormalizeNODES ( wNode *node, int noNodes )
|
||||
{
|
||||
for ( int i = 0; i < noNodes; i++ ) {
|
||||
int gcd = GCD ( node [i].dx, node [i].dy );
|
||||
node [i].dx /= gcd;
|
||||
node [i].dy /= gcd;
|
||||
if ( node [i].dx == 0 ) node [i].dy = sgn ( node [i].dy );
|
||||
if ( node [i].dy == 0 ) node [i].dx = sgn ( node [i].dx );
|
||||
if (( node [i].dx < 0 ) || (( node [i].dx == 0 ) && ( node [i].dy < 0 ))) {
|
||||
node [i].dx = -node [i].dx;
|
||||
node [i].dy = -node [i].dy;
|
||||
swap ( node [i].side [0], node [i].side [1] );
|
||||
swap ( node [i].child [0], node [i].child [1] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int SortSegs ( const void *ptr1, const void *ptr2 )
|
||||
{
|
||||
int dif = (( wSegs * ) ptr1)->lineDef - (( wSegs * ) ptr2)->lineDef;
|
||||
if ( dif ) return dif;
|
||||
|
||||
return (( wSegs * ) ptr1)->flip - (( wSegs * ) ptr2)->flip ?
|
||||
(( wSegs * ) ptr1)->flip - (( wSegs * ) ptr2)->flip :
|
||||
(( wSegs * ) ptr1)->offset - (( wSegs * ) ptr2)->offset;
|
||||
}
|
||||
|
||||
bool LinesMatch ( const wNode &node1, const wNode &node2 )
|
||||
{
|
||||
if (( node1.dx != node2.dx ) || ( node1.dy != node2.dy )) return false;
|
||||
|
||||
if ( node1.dx == 0 ) return ( node1.x == node2.x ) ? true : false;
|
||||
if ( node1.dy == 0 ) return ( node1.y == node2.y ) ? true : false;
|
||||
|
||||
double tx = ( double ) ( node2.x - node1.x ) / ( double ) node1.dx;
|
||||
double ty = ( double ) ( node2.y - node1.y ) / ( double ) node1.dy;
|
||||
|
||||
double delta = fabs ( tx - ty );
|
||||
|
||||
if ( delta < 0.001 ) return true;
|
||||
|
||||
if ( delta < 1.000 ) printf ( "tx = %g ty = %g\n", tx, ty );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *locationString;
|
||||
|
||||
void printNode ( const wNode &node, int index )
|
||||
{
|
||||
printf ( "\n%5d - (%5d,%5d) (%5d,%5d) L: %c %5d R: %c %5d",
|
||||
index, node.x, node.y, node.dx, node.dy,
|
||||
( node.child [0] & 0x8000 ) ? 'S' : 'N', node.child [0] & 0x7FFF, ( node.child [1] & 0x8000 ) ? 'S' : 'N', node.child [1] & 0x7FFF );
|
||||
}
|
||||
|
||||
static DoomLevel *srcLevel;
|
||||
static DoomLevel *tgtLevel;
|
||||
|
||||
int CompareSSECTOR ( int srcIndex, int tgtIndex )
|
||||
{
|
||||
srcIndex &= 0x7FFF;
|
||||
tgtIndex &= 0x7FFF;
|
||||
|
||||
// qsort ( segs, noSegs, sizeof ( SEG ), SortSegs );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CompareNODE ( int srcIndex, int tgtIndex, char *location )
|
||||
{
|
||||
int length = location - locationString;
|
||||
|
||||
if (( srcIndex & 0x8000 ) != ( tgtIndex & 0x8000 )) {
|
||||
printf ( "\n%*.*s: Leaf != Node", length, length, locationString );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( srcIndex & 0x8000 ) {
|
||||
return CompareSSECTOR ( srcIndex, tgtIndex );
|
||||
}
|
||||
|
||||
const wNode &src = srcLevel->GetNodes () [srcIndex];
|
||||
const wNode &tgt = tgtLevel->GetNodes () [tgtIndex];
|
||||
|
||||
if ( LinesMatch ( src, tgt ) == false ) {
|
||||
int length = location - locationString;
|
||||
printf ( "\n%*.*s:", length, length, locationString );
|
||||
printNode ( src, srcIndex );
|
||||
printNode ( tgt, tgtIndex );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
*location = 'R';
|
||||
count += CompareNODE ( src.child [0], tgt.child [0], location + 1 );
|
||||
|
||||
*location = 'L';
|
||||
count += CompareNODE ( src.child [1], tgt.child [1], location + 1 );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int ProcessLevel ( char *name, wadList *myList1, wadList *myList2 )
|
||||
{
|
||||
cprintf ( "\r %-*.*s: ", MAX_LUMP_NAME, MAX_LUMP_NAME, name );
|
||||
GetXY ( &startX, &startY );
|
||||
|
||||
int mismatches = 0;
|
||||
|
||||
srcLevel = NULL;
|
||||
tgtLevel = NULL;
|
||||
|
||||
const wadListDirEntry *dir = myList1->FindWAD ( name );
|
||||
srcLevel = new DoomLevel ( name, dir->wad );
|
||||
if ( srcLevel->IsValid ( true ) == false ) {
|
||||
Status ( "This level is not valid... " );
|
||||
mismatches = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dir = myList2->FindWAD ( name );
|
||||
tgtLevel = new DoomLevel ( name, dir->wad );
|
||||
if ( tgtLevel->IsValid ( true ) == false ) {
|
||||
Status ( "This level is not valid... " );
|
||||
mismatches = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
{
|
||||
NormalizeNODES (( wNode * ) srcLevel->GetNodes (), srcLevel->NodeCount ());
|
||||
NormalizeNODES (( wNode * ) tgtLevel->GetNodes (), tgtLevel->NodeCount ());
|
||||
|
||||
int noNodes = max ( srcLevel->NodeCount (), tgtLevel->NodeCount ());
|
||||
|
||||
locationString = new char [ noNodes ];
|
||||
|
||||
mismatches = CompareNODE ( srcLevel->NodeCount () - 1, tgtLevel->NodeCount () - 1, locationString );
|
||||
|
||||
delete [] locationString;
|
||||
|
||||
if ( mismatches == 0 ) Status ( "NODES Match" );
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
cprintf ( "\r\n" );
|
||||
|
||||
delete tgtLevel;
|
||||
delete srcLevel;
|
||||
|
||||
return mismatches;
|
||||
}
|
||||
|
||||
int main ( int argc, const char *argv[] )
|
||||
{
|
||||
fprintf ( stderr, "Compare Version %s (c) 2003-2004 Marc Rousseau\n\n", VERSION );
|
||||
|
||||
if ( argc == 1 ) {
|
||||
printHelp ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
SaveConsoleSettings ();
|
||||
|
||||
int argIndex = 1, changes = 0;
|
||||
|
||||
while ( KeyPressed ()) GetKey ();
|
||||
|
||||
do {
|
||||
|
||||
argIndex = parseArgs ( argIndex, argv );
|
||||
if ( argIndex < 0 ) break;
|
||||
|
||||
char wadFileName1 [ 256 ];
|
||||
wadList *myList1 = getInputFiles ( argv [argIndex++], wadFileName1 );
|
||||
if ( myList1->IsEmpty ()) { changes = -1000; break; }
|
||||
|
||||
char wadFileName2 [ 256 ];
|
||||
wadList *myList2 = getInputFiles ( argv [argIndex++], wadFileName2 );
|
||||
if ( myList2->IsEmpty ()) { changes = -1000; break; }
|
||||
|
||||
cprintf ( "Comparing: %s and %s\r\n\n", wadFileName1, wadFileName2 );
|
||||
|
||||
char levelNames [MAX_LEVELS+1][MAX_LUMP_NAME];
|
||||
argIndex = getLevels ( argIndex, argv, levelNames, myList1 );
|
||||
|
||||
if ( levelNames [0][0] == '\0' ) {
|
||||
fprintf ( stderr, "Unable to find any valid levels in %s\n", wadFileName1 );
|
||||
break;
|
||||
}
|
||||
|
||||
int noLevels = 0;
|
||||
|
||||
do {
|
||||
|
||||
changes += ProcessLevel ( levelNames [noLevels++], myList1, myList2 );
|
||||
if ( KeyPressed () && ( GetKey () == 0x1B )) break;
|
||||
|
||||
} while ( levelNames [noLevels][0] );
|
||||
|
||||
cprintf ( "\r\n" );
|
||||
|
||||
delete myList1;
|
||||
delete myList2;
|
||||
|
||||
} while ( argv [argIndex] );
|
||||
|
||||
RestoreConsoleSettings ();
|
||||
|
||||
return changes;
|
||||
}
|
|
@ -0,0 +1,439 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: bspinfo.cpp
|
||||
// Date: 11-Oct-1995
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: An application to analyze the contents of a BSP tree
|
||||
//
|
||||
// Copyright (c) 1995-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "wad.hpp"
|
||||
#include "level.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
#if defined ( __OS2__ )
|
||||
#include <conio.h>
|
||||
#include <io.h>
|
||||
#elif defined ( __WIN32__ )
|
||||
#include <conio.h>
|
||||
#include <io.h>
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error This program must be compiled as a 32-bit app.
|
||||
#endif
|
||||
|
||||
DBG_REGISTER ( __FILE__ );
|
||||
|
||||
#define VERSION "1.3"
|
||||
#define BANNER "BSPInfo Version " VERSION " (c) 1995-2004 Marc Rousseau"
|
||||
#define MAX_LEVELS 99
|
||||
|
||||
#if defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
|
||||
#define stricmp strcasecmp
|
||||
|
||||
extern char *strupr ( char *ptr );
|
||||
|
||||
#endif
|
||||
|
||||
struct {
|
||||
bool Tree;
|
||||
} flags;
|
||||
|
||||
void printHelp ()
|
||||
{
|
||||
fprintf ( stderr, "Usage: bspInfo [-options] filename[.wad] [level[+level]]\n" );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " -x+ turn on option -x- turn off option %c = default\n", DEFAULT_CHAR );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " -t - Display NODE tree\n" );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " level - ExMy for DOOM / Heretic\n" );
|
||||
fprintf ( stderr, " MAPxx for DOOM II / HEXEN\n" );
|
||||
}
|
||||
|
||||
int parseArgs ( int index, const char *argv [] )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "parseArgs", true );
|
||||
|
||||
bool errors = false;
|
||||
while ( argv [ index ] ) {
|
||||
|
||||
if ( argv [index][0] != '-' ) break;
|
||||
|
||||
char *localCopy = strdup ( argv [ index ]);
|
||||
char *ptr = localCopy + 1;
|
||||
strupr ( localCopy );
|
||||
|
||||
bool localError = false;
|
||||
while ( *ptr && ( localError == false )) {
|
||||
int option = *ptr++;
|
||||
bool setting = true;
|
||||
if (( *ptr == '+' ) || ( *ptr == '-' )) {
|
||||
setting = ( *ptr == '-' ) ? false : true;
|
||||
ptr++;
|
||||
}
|
||||
switch ( option ) {
|
||||
case 'T' : flags.Tree = setting; break;
|
||||
default : localError = true;
|
||||
}
|
||||
}
|
||||
if ( localError ) {
|
||||
errors = true;
|
||||
int offset = ptr - localCopy - 1;
|
||||
size_t width = strlen ( ptr ) + 1;
|
||||
fprintf ( stderr, "Unrecognized parameter '%*.*s'\n", width, width, argv [index] + offset );
|
||||
}
|
||||
free ( localCopy );
|
||||
index++;
|
||||
}
|
||||
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int getLevels ( int argIndex, const char *argv [], char names [][MAX_LUMP_NAME], wadList *list )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "getLevels", true );
|
||||
|
||||
int index = 0, errors = 0;
|
||||
|
||||
char buffer [128];
|
||||
buffer [0] = '\0';
|
||||
if ( argv [argIndex] ) {
|
||||
strcpy ( buffer, argv [argIndex] );
|
||||
strupr ( buffer );
|
||||
}
|
||||
char *ptr = strtok ( buffer, "+" );
|
||||
|
||||
// See if the user requested specific levels
|
||||
if ( WAD::IsMap ( ptr )) {
|
||||
argIndex++;
|
||||
while ( ptr ) {
|
||||
if ( WAD::IsMap ( ptr )) {
|
||||
if ( list->FindWAD ( ptr )) {
|
||||
strcpy ( names [index++], ptr );
|
||||
} else {
|
||||
fprintf ( stderr, " Could not find %s\n", ptr, errors++ );
|
||||
}
|
||||
} else {
|
||||
fprintf ( stderr, " %s is not a valid name for a level\n", ptr, errors++ );
|
||||
}
|
||||
ptr = strtok ( NULL, "+" );
|
||||
}
|
||||
} else {
|
||||
int size = list->DirSize ();
|
||||
const wadListDirEntry *dir = list->GetDir ( 0 );
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
if ( dir->wad->IsMap ( dir->entry->name )) {
|
||||
// Make sure it's really a level
|
||||
if ( strcmp ( dir[1].entry->name, "THINGS" ) == 0 ) {
|
||||
if ( index == MAX_LEVELS ) {
|
||||
fprintf ( stderr, "ERROR: Too many levels in WAD - ignoring %s!\n", dir->entry->name, errors++ );
|
||||
} else {
|
||||
memcpy ( names [index++], dir->entry->name, MAX_LUMP_NAME );
|
||||
}
|
||||
}
|
||||
}
|
||||
dir++;
|
||||
}
|
||||
}
|
||||
memset ( names [index], 0, MAX_LUMP_NAME );
|
||||
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return argIndex;
|
||||
}
|
||||
|
||||
void EnsureExtension ( char *fileName, const char *ext )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "EnsureExtension", true );
|
||||
|
||||
// See if the file exists first
|
||||
FILE *file = fopen ( fileName, "rb" );
|
||||
if ( file != NULL ) {
|
||||
fclose ( file );
|
||||
return;
|
||||
}
|
||||
|
||||
size_t length = strlen ( fileName );
|
||||
if ( stricmp ( &fileName [length-4], ext ) != 0 ) {
|
||||
strcat ( fileName, ext );
|
||||
}
|
||||
}
|
||||
|
||||
const char *TypeName ( eWadType type )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "TypeName", true );
|
||||
|
||||
const char *name = NULL;
|
||||
switch ( type ) {
|
||||
case wt_DOOM : name = "DOOM"; break;
|
||||
case wt_DOOM2 : name = "DOOM2"; break;
|
||||
case wt_HERETIC : name = "Heretic"; break;
|
||||
case wt_HEXEN : name = "Hexen"; break;
|
||||
default : name = "<Unknown>"; break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
wadList *getInputFiles ( const char *cmdLine, char *wadFileName )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "getInputFiles", true );
|
||||
|
||||
char *listNames = wadFileName;
|
||||
wadList *myList = new wadList;
|
||||
|
||||
if ( cmdLine == NULL ) return myList;
|
||||
|
||||
char temp [ 256 ];
|
||||
strcpy ( temp, cmdLine );
|
||||
char *ptr = strtok ( temp, "+" );
|
||||
|
||||
int errors = 0;
|
||||
|
||||
while ( ptr && *ptr ) {
|
||||
char wadName [ 256 ];
|
||||
strcpy ( wadName, ptr );
|
||||
EnsureExtension ( wadName, ".wad" );
|
||||
|
||||
WAD *wad = new WAD ( wadName );
|
||||
if ( wad->Status () != ws_OK ) {
|
||||
const char *msg;
|
||||
switch ( wad->Status ()) {
|
||||
case ws_INVALID_FILE : msg = "The file %s does not exist\n"; break;
|
||||
case ws_CANT_READ : msg = "Can't open the file %s for read access\n"; break;
|
||||
case ws_INVALID_WAD : msg = "%s is not a valid WAD file\n"; break;
|
||||
default : msg = "** Unexpected Error opening %s **\n"; break;
|
||||
}
|
||||
fprintf ( stderr, msg, wadName );
|
||||
delete wad;
|
||||
} else {
|
||||
if ( ! myList->IsEmpty ()) {
|
||||
cprintf ( "Merging: %s with %s\r\n", wadName, listNames );
|
||||
*wadFileName++ = '+';
|
||||
}
|
||||
if ( myList->Add ( wad ) == false ) {
|
||||
errors++;
|
||||
if ( myList->Type () != wt_UNKNOWN ) {
|
||||
fprintf ( stderr, "ERROR: %s is not a %s PWAD.\n", wadName, TypeName ( myList->Type ()));
|
||||
} else {
|
||||
fprintf ( stderr, "ERROR: %s is not the same type.\n", wadName );
|
||||
}
|
||||
delete wad;
|
||||
} else {
|
||||
char *end = wadName + strlen ( wadName ) - 1;
|
||||
while (( end > wadName ) && ( *end != SEPERATOR )) end--;
|
||||
if ( *end == SEPERATOR ) end++;
|
||||
wadFileName += sprintf ( wadFileName, "%s", end );
|
||||
}
|
||||
}
|
||||
ptr = strtok ( NULL, "+" );
|
||||
}
|
||||
|
||||
if ( wadFileName [-1] == '+' ) wadFileName [-1] = '\0';
|
||||
if ( myList->wadCount () > 1 ) cprintf ( "\r\n" );
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return myList;
|
||||
}
|
||||
|
||||
const wNode *nodes;
|
||||
int totalDepth;
|
||||
|
||||
int Traverse ( int index, int depth, int &diagonals, int &balance, int &lChildren, int &rChildren )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "Traverse", false );
|
||||
|
||||
const wNode *node = &nodes [ index ];
|
||||
|
||||
if ( flags.Tree ) printf ( "(%5d,%5d) [%5d,%5d]\n", node->x, node->y, node->dx, node->dy );
|
||||
|
||||
if (( node->dx != 0 ) && ( node->dy != 0 )) diagonals++;
|
||||
|
||||
int lIndex = node->child [0];
|
||||
int rIndex = node->child [1];
|
||||
|
||||
if (( lIndex & 0x8000 ) == ( rIndex & 0x8000 )) balance++;
|
||||
|
||||
int lDepth = 0, rDepth = 0;
|
||||
|
||||
depth++;
|
||||
|
||||
if ( flags.Tree ) printf ( "%5d %*.*sLeft - ", depth, depth*2, depth*2, "" );
|
||||
|
||||
if (( lIndex & 0x8000 ) == 0 ) {
|
||||
int left = 0, right = 0;
|
||||
lDepth = Traverse ( lIndex, depth, diagonals, balance, left, right );
|
||||
lChildren = 1 + left + right;
|
||||
} else {
|
||||
if ( flags.Tree ) printf ( "** NONE **\n" );
|
||||
lDepth = depth;
|
||||
totalDepth += depth + 1;
|
||||
}
|
||||
|
||||
if ( flags.Tree ) printf ( "%5d %*.*sRight - ", depth, depth*2, depth*2, "" );
|
||||
|
||||
if (( rIndex & 0x8000 ) == 0 ) {
|
||||
int left = 0, right = 0;
|
||||
rDepth = Traverse ( rIndex, depth, diagonals, balance, left, right );
|
||||
rChildren = 1 + left + right;
|
||||
} else {
|
||||
if ( flags.Tree ) printf ( "** NONE **\n" );
|
||||
rDepth = depth;
|
||||
totalDepth += depth + 1;
|
||||
}
|
||||
|
||||
return (( lDepth > rDepth ) ? lDepth : rDepth );
|
||||
}
|
||||
|
||||
void AnalyzeBSP ( DoomLevel *curLevel )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "AnalyzeBSP", true );
|
||||
|
||||
if ( curLevel->IsValid ( true, true ) == false ) {
|
||||
printf ( "******** Invalid level ********" );
|
||||
return;
|
||||
}
|
||||
|
||||
totalDepth = 0;
|
||||
|
||||
nodes = curLevel->GetNodes ();
|
||||
int balance = 0, diagonals = 0;
|
||||
if ( flags.Tree ) printf ( "\n\nROOT: " );
|
||||
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int depth = Traverse ( curLevel->NodeCount () - 1, 0, diagonals, balance, left, right );
|
||||
|
||||
const wSegs *seg = curLevel->GetSegs ();
|
||||
const wLineDef *lineDef = curLevel->GetLineDefs ();
|
||||
|
||||
bool *lineUsed = new bool [ curLevel->LineDefCount ()];
|
||||
memset ( lineUsed, false, sizeof ( bool ) * curLevel->LineDefCount ());
|
||||
for ( int i = 0; i < curLevel->SegCount (); i++, seg++ ) {
|
||||
lineUsed [ seg->lineDef ] = true;
|
||||
}
|
||||
|
||||
int sideDefs = 0;
|
||||
for ( int i = 0; i < curLevel->LineDefCount (); i++ ) {
|
||||
if ( lineUsed [i] == false ) continue;
|
||||
if ( lineDef[i].sideDef[0] != NO_SIDEDEF ) sideDefs++;
|
||||
if ( lineDef[i].sideDef[1] != NO_SIDEDEF ) sideDefs++;
|
||||
}
|
||||
|
||||
int splits = curLevel->SegCount () - sideDefs;
|
||||
|
||||
int noLeafs = curLevel->SubSectorCount ();
|
||||
int optDepth = ( int ) ceil ( log (( float ) noLeafs ) / log ( 2.0 ));
|
||||
int maxLeafs = ( int ) pow ( 2, optDepth );
|
||||
int minDepth = noLeafs * ( optDepth + 1 ) - maxLeafs;
|
||||
int maxDepth = noLeafs * (( noLeafs - 1 ) / 2 + 1 ) - 1;
|
||||
|
||||
double minScore = ( double ) minDepth / ( double ) maxDepth;
|
||||
double score = ( double ) minDepth / ( double ) totalDepth;
|
||||
score = ( score - minScore ) / ( 1 - minScore );
|
||||
|
||||
if ( ! flags.Tree ) {
|
||||
float avgDepth = noLeafs ? ( float ) totalDepth / ( float ) noLeafs : 0;
|
||||
printf ( "%2d ", depth );
|
||||
printf ( "%4.1f ", avgDepth );
|
||||
printf ( "%5.3f ", score );
|
||||
printf ( "%5.3f ", ( left < right ) ? ( double ) left / ( double ) right : ( double ) right / ( double ) left );
|
||||
printf ( "%5d - %4.1f%% ", splits, 100.0 * splits / sideDefs );
|
||||
printf ( "%5d - %4.1f%% ", diagonals, 100.0 * diagonals / curLevel->NodeCount ());
|
||||
printf ( "%5d ", curLevel->NodeCount ());
|
||||
printf ( "%5d", curLevel->SegCount ());
|
||||
}
|
||||
}
|
||||
|
||||
int main ( int argc, const char *argv[] )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "main", true );
|
||||
|
||||
SaveConsoleSettings ();
|
||||
|
||||
cprintf ( "%s\r\n\r\n", BANNER );
|
||||
if ( ! isatty ( fileno ( stdout ))) fprintf ( stdout, "%s\n\n", BANNER );
|
||||
if ( ! isatty ( fileno ( stderr ))) fprintf ( stderr, "%s\n\n", BANNER );
|
||||
|
||||
if ( argc == 1 ) {
|
||||
printHelp ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
flags.Tree = false;
|
||||
|
||||
int argIndex = 1;
|
||||
do {
|
||||
|
||||
argIndex = parseArgs ( argIndex, argv );
|
||||
if ( argIndex < 0 ) break;
|
||||
|
||||
char wadFileName [ 256 ];
|
||||
wadList *myList = getInputFiles ( argv [argIndex++], wadFileName );
|
||||
if ( myList->IsEmpty ()) break;
|
||||
printf ( "Analyzing: %s\n\n", wadFileName );
|
||||
|
||||
char levelNames [MAX_LEVELS+1][MAX_LUMP_NAME];
|
||||
argIndex = getLevels ( argIndex, argv, levelNames, myList );
|
||||
|
||||
if ( levelNames [0][0] == '\0' ) {
|
||||
fprintf ( stderr, "Unable to find any valid levels in %s\n", wadFileName );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! flags.Tree ) {
|
||||
printf ( " Max Avg\n" );
|
||||
printf ( " Depth Depth FOM Balance Splits Diagonals Nodes Segs\n" );
|
||||
}
|
||||
|
||||
int noLevels = 0;
|
||||
|
||||
do {
|
||||
|
||||
const wadListDirEntry *dir = myList->FindWAD ( levelNames [ noLevels ]);
|
||||
DoomLevel *curLevel = new DoomLevel ( levelNames [ noLevels ], dir->wad );
|
||||
printf ( "%8.8s: ", levelNames [ noLevels++ ]);
|
||||
AnalyzeBSP ( curLevel );
|
||||
printf ( "\n" );
|
||||
delete curLevel;
|
||||
|
||||
} while ( levelNames [noLevels][0] );
|
||||
|
||||
printf ( "\n" );
|
||||
|
||||
delete myList;
|
||||
|
||||
} while ( argv [argIndex] );
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,494 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: compare.cpp
|
||||
// Date: 16-Jan-1996
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Compares two REJECT structures and report any differences
|
||||
//
|
||||
// Copyright (c) 1996-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined ( __OS2__ )
|
||||
#define INCL_DOS
|
||||
#define INCL_SUB
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include <io.h>
|
||||
#include <os2.h>
|
||||
#elif defined ( __WIN32__ )
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#include <wincon.h>
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error This program must be compiled as a 32-bit app.
|
||||
#endif
|
||||
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "wad.hpp"
|
||||
#include "level.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
DBG_REGISTER ( __FILE__ );
|
||||
|
||||
#define VERSION "1.3"
|
||||
#define BANNER "compare Version " VERSION " (c) 1996-2004 Marc Rousseau"
|
||||
#define MAX_LEVELS 99
|
||||
|
||||
#define UNSUPPORTED_FEATURE -1
|
||||
#define UNRECOGNIZED_PARAMETER -2
|
||||
|
||||
#if defined ( __BORLANDC__ )
|
||||
#pragma option -x -xf
|
||||
#endif
|
||||
|
||||
#if defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
|
||||
#define stricmp strcasecmp
|
||||
|
||||
extern char *strupr ( char *ptr );
|
||||
|
||||
#endif
|
||||
|
||||
void printHelp ()
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "printHelp", true );
|
||||
|
||||
fprintf ( stderr, "Usage: compare {-options} filename1[.wad] filename2[.wad] [level{+level}]\n" );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " -x+ turn on option -x- turn off option %c = default\n", DEFAULT_CHAR );
|
||||
fprintf ( stderr, "\n" );
|
||||
fprintf ( stderr, " level - ExMy for DOOM / Heretic\n" );
|
||||
fprintf ( stderr, " MAPxx for DOOM II / HEXEN\n" );
|
||||
}
|
||||
|
||||
int parseArgs ( int index, const char *argv[] )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "parseArgs", true );
|
||||
|
||||
bool errors = false;
|
||||
while ( argv [ index ] ) {
|
||||
|
||||
if ( argv [index][0] != '-' ) break;
|
||||
|
||||
char *localCopy = strdup ( argv [ index ]);
|
||||
char *ptr = localCopy + 1;
|
||||
strupr ( localCopy );
|
||||
|
||||
bool localError = false;
|
||||
while ( *ptr && ( localError == false )) {
|
||||
int option = *ptr++;
|
||||
bool setting = true;
|
||||
if (( *ptr == '+' ) || ( *ptr == '-' )) {
|
||||
setting = ( *ptr == '-' ) ? false : true;
|
||||
ptr++;
|
||||
}
|
||||
switch ( option ) {
|
||||
case -1 :
|
||||
default : localError = true;
|
||||
}
|
||||
}
|
||||
if ( localError ) {
|
||||
errors = true;
|
||||
int offset = ptr - localCopy - 1;
|
||||
size_t width = strlen ( ptr ) + 1;
|
||||
fprintf ( stderr, "Unrecognized parameter '%*.*s'\n", width, width, argv [index] + offset );
|
||||
}
|
||||
free ( localCopy );
|
||||
index++;
|
||||
}
|
||||
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int getLevels ( int argIndex, const char *argv[], char names [][MAX_LUMP_NAME], wadList *list1, wadList *list2 )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "getLevels", true );
|
||||
|
||||
int index = 0, errors = 0;
|
||||
|
||||
char buffer [128];
|
||||
buffer [0] = '\0';
|
||||
if ( argv [argIndex] ) {
|
||||
strcpy ( buffer, argv [argIndex] );
|
||||
strupr ( buffer );
|
||||
}
|
||||
char *ptr = strtok ( buffer, "+" );
|
||||
|
||||
// See if the user requested specific levels
|
||||
if ( WAD::IsMap ( ptr )) {
|
||||
argIndex++;
|
||||
while ( ptr ) {
|
||||
if ( WAD::IsMap ( ptr )) {
|
||||
if ( list1->FindWAD ( ptr )) {
|
||||
strcpy ( names [index++], ptr );
|
||||
} else {
|
||||
fprintf ( stderr, " Could not find %s\n", ptr, errors++ );
|
||||
}
|
||||
} else {
|
||||
fprintf ( stderr, " %s is not a valid name for a level\n", ptr, errors++ );
|
||||
}
|
||||
ptr = strtok ( NULL, "+" );
|
||||
}
|
||||
} else {
|
||||
int size = list1->DirSize ();
|
||||
const wadListDirEntry *dir = list1->GetDir ( 0 );
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
if ( dir->wad->IsMap ( dir->entry->name )) {
|
||||
if ( index == MAX_LEVELS ) {
|
||||
fprintf ( stderr, "ERROR: Too many levels in WAD - ignoring %s!\n", dir->entry->name, errors++ );
|
||||
} else {
|
||||
memcpy ( names [index++], dir->entry->name, MAX_LUMP_NAME );
|
||||
}
|
||||
}
|
||||
dir++;
|
||||
}
|
||||
}
|
||||
memset ( names [index], 0, MAX_LUMP_NAME );
|
||||
|
||||
// Remove any maps that aren't in both files
|
||||
for ( int i = 0; names [i][0]; i++ ) {
|
||||
if ( list2->FindWAD ( names [i] ) == NULL ) {
|
||||
memcpy ( names + i, names + i + 1, ( index - i ) * MAX_LUMP_NAME );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return argIndex;
|
||||
}
|
||||
|
||||
void EnsureExtension ( char *fileName, const char *ext )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "EnsureExtension", true );
|
||||
|
||||
// See if the file exists first
|
||||
FILE *file = fopen ( fileName, "rb" );
|
||||
if ( file != NULL ) {
|
||||
fclose ( file );
|
||||
return;
|
||||
}
|
||||
|
||||
size_t length = strlen ( fileName );
|
||||
if ( stricmp ( &fileName [length-4], ext ) != 0 ) {
|
||||
strcat ( fileName, ext );
|
||||
}
|
||||
}
|
||||
|
||||
const char *TypeName ( eWadType type )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "TypeName", true );
|
||||
|
||||
const char *name = NULL;
|
||||
switch ( type ) {
|
||||
case wt_DOOM : name = "DOOM"; break;
|
||||
case wt_DOOM2 : name = "DOOM2"; break;
|
||||
case wt_HERETIC : name = "Heretic"; break;
|
||||
case wt_HEXEN : name = "Hexen"; break;
|
||||
default : name = "<Unknown>"; break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
wadList *getInputFiles ( const char *cmdLine, char *wadFileName )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "getInputFiles", true );
|
||||
|
||||
char *listNames = wadFileName;
|
||||
wadList *myList = new wadList;
|
||||
|
||||
if ( cmdLine == NULL ) return myList;
|
||||
|
||||
char temp [ 256 ];
|
||||
strcpy ( temp, cmdLine );
|
||||
char *ptr = strtok ( temp, "+" );
|
||||
|
||||
int errors = 0;
|
||||
|
||||
while ( ptr && *ptr ) {
|
||||
char wadName [ 256 ];
|
||||
strcpy ( wadName, ptr );
|
||||
EnsureExtension ( wadName, ".wad" );
|
||||
|
||||
WAD *wad = new WAD ( wadName );
|
||||
if ( wad->Status () != ws_OK ) {
|
||||
const char *msg;
|
||||
switch ( wad->Status ()) {
|
||||
case ws_INVALID_FILE : msg = "The file %s does not exist\n"; break;
|
||||
case ws_CANT_READ : msg = "Can't open the file %s for read access\n"; break;
|
||||
case ws_INVALID_WAD : msg = "%s is not a valid WAD file\n"; break;
|
||||
default : msg = "** Unexpected Error opening %s **\n"; break;
|
||||
}
|
||||
fprintf ( stderr, msg, wadName );
|
||||
delete wad;
|
||||
} else {
|
||||
if ( ! myList->IsEmpty ()) {
|
||||
cprintf ( "Merging: %s with %s\r\n", wadName, listNames );
|
||||
*wadFileName++ = '+';
|
||||
}
|
||||
if ( myList->Add ( wad ) == false ) {
|
||||
errors++;
|
||||
if ( myList->Type () != wt_UNKNOWN ) {
|
||||
fprintf ( stderr, "ERROR: %s is not a %s PWAD.\n", wadName, TypeName ( myList->Type ()));
|
||||
} else {
|
||||
fprintf ( stderr, "ERROR: %s is not the same type.\n", wadName );
|
||||
}
|
||||
delete wad;
|
||||
} else {
|
||||
char *end = wadName + strlen ( wadName ) - 1;
|
||||
while (( end > wadName ) && ( *end != SEPERATOR )) end--;
|
||||
if ( *end == SEPERATOR ) end++;
|
||||
wadFileName += sprintf ( wadFileName, "%s", end );
|
||||
}
|
||||
}
|
||||
ptr = strtok ( NULL, "+" );
|
||||
}
|
||||
|
||||
if ( wadFileName [-1] == '+' ) wadFileName [-1] = '\0';
|
||||
if ( myList->wadCount () > 1 ) cprintf ( "\r\n" );
|
||||
if ( errors ) fprintf ( stderr, "\n" );
|
||||
|
||||
return myList;
|
||||
}
|
||||
|
||||
int CompareREJECT ( DoomLevel *srcLevel, DoomLevel *tgtLevel )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "CompareREJECT", true );
|
||||
|
||||
bool match = true;
|
||||
int noSectors = srcLevel->SectorCount ();
|
||||
char *srcPtr = ( char * ) srcLevel->GetReject ();
|
||||
char *tgtPtr = ( char * ) tgtLevel->GetReject ();
|
||||
|
||||
int **vis2hid = new int * [ noSectors ];
|
||||
int **hid2vis = new int * [ noSectors ];
|
||||
|
||||
int *v2hCount = new int [ noSectors ];
|
||||
int *h2vCount = new int [ noSectors ];
|
||||
|
||||
int bits = 8;
|
||||
int srcVal = *srcPtr++;
|
||||
int tgtVal = *tgtPtr++;
|
||||
int dif = srcVal ^ tgtVal;
|
||||
for ( int i = 0; i < noSectors; i++ ) {
|
||||
vis2hid [i] = new int [ noSectors ];
|
||||
hid2vis [i] = new int [ noSectors ];
|
||||
memset ( vis2hid [i], 0, noSectors * sizeof ( int ));
|
||||
memset ( hid2vis [i], 0, noSectors * sizeof ( int ));
|
||||
v2hCount [i] = 0;
|
||||
h2vCount [i] = 0;
|
||||
for ( int j = 0; j < noSectors; j++ ) {
|
||||
if ( dif & 1 ) {
|
||||
if ( srcVal & 1 ) {
|
||||
hid2vis [i][h2vCount [i]++] = j;
|
||||
} else {
|
||||
vis2hid [i][v2hCount [i]++] = j;
|
||||
}
|
||||
match = false;
|
||||
}
|
||||
if ( --bits == 0 ) {
|
||||
bits = 8;
|
||||
srcVal = *srcPtr++;
|
||||
tgtVal = *tgtPtr++;
|
||||
dif = srcVal ^ tgtVal;
|
||||
} else {
|
||||
srcVal >>= 1;
|
||||
tgtVal >>= 1;
|
||||
dif >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
for ( int i = 0; i < noSectors; i++ ) {
|
||||
if (( v2hCount [i] == 0 ) && ( h2vCount [i] == 0 )) continue;
|
||||
bool v2h = false;
|
||||
for ( int j = 0; j < v2hCount [i]; j++ ) {
|
||||
int index = vis2hid [i][j];
|
||||
if (( v2hCount [i] > v2hCount [index] ) ||
|
||||
(( v2hCount [i] == v2hCount [index] ) && ( i > index ))) {
|
||||
v2h = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool h2v = false;
|
||||
for ( int j = 0; j < h2vCount [i]; j++ ) {
|
||||
int index = hid2vis [i][j];
|
||||
if (( h2vCount [i] > h2vCount [index] ) ||
|
||||
(( h2vCount [i] == h2vCount [index] ) && ( i > index ))) {
|
||||
h2v = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( v2h == true ) {
|
||||
if ( first == false ) printf ( " " );
|
||||
printf ( "vis->hid %5d:", i );
|
||||
for ( int j = 0; j < v2hCount [i]; j++ ) {
|
||||
printf ( " %d", vis2hid [i][j] );
|
||||
}
|
||||
printf ( "\n" );
|
||||
first = false;
|
||||
}
|
||||
if ( h2v == true ) {
|
||||
if ( first == false ) printf ( " " );
|
||||
printf ( "hid->vis %5d:", i );
|
||||
for ( int j = 0; j < h2vCount [i]; j++ ) {
|
||||
printf ( " %d", hid2vis [i][j] );
|
||||
}
|
||||
printf ( "\n" );
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( match == true ) printf ( "Perfect Match\n" );
|
||||
|
||||
for ( int i = 0; i < noSectors; i++ ) {
|
||||
delete [] vis2hid [i];
|
||||
delete [] hid2vis [i];
|
||||
}
|
||||
|
||||
delete [] vis2hid;
|
||||
delete [] hid2vis;
|
||||
|
||||
delete [] v2hCount;
|
||||
delete [] h2vCount;
|
||||
|
||||
return match ? 0 : 1;
|
||||
}
|
||||
|
||||
int ProcessLevel ( char *name, wadList *myList1, wadList *myList2 )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "ProcessLevel", true );
|
||||
|
||||
int change;
|
||||
cprintf ( " %-*.*s: ", MAX_LUMP_NAME, MAX_LUMP_NAME, name );
|
||||
GetXY ( &startX, &startY );
|
||||
|
||||
DoomLevel *tgtLevel = NULL;
|
||||
const wadListDirEntry *dir = myList1->FindWAD ( name );
|
||||
DoomLevel *srcLevel = new DoomLevel ( name, dir->wad );
|
||||
if ( srcLevel->IsValid ( true ) == false ) {
|
||||
change = -1000;
|
||||
cprintf ( "The source level is not valid... \r\n" );
|
||||
goto done;
|
||||
}
|
||||
|
||||
dir = myList2->FindWAD ( name );
|
||||
tgtLevel = new DoomLevel ( name, dir->wad );
|
||||
if ( tgtLevel->IsValid ( true ) == false ) {
|
||||
change = -1000;
|
||||
cprintf ( "The target level is not valid... \r\n" );
|
||||
goto done;
|
||||
}
|
||||
if ( srcLevel->RejectSize () != tgtLevel->RejectSize ()) {
|
||||
change = -1000;
|
||||
cprintf ( "The reject maps aren't the same size\r\n" );
|
||||
goto done;
|
||||
}
|
||||
|
||||
change = CompareREJECT ( srcLevel, tgtLevel );
|
||||
|
||||
done:
|
||||
|
||||
delete tgtLevel;
|
||||
delete srcLevel;
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
#if defined ( __BORLANDC__ )
|
||||
#include <dir.h>
|
||||
#endif
|
||||
|
||||
int main ( int argc, const char *argv[] )
|
||||
{
|
||||
FUNCTION_ENTRY ( NULL, "main", true );
|
||||
|
||||
SaveConsoleSettings ();
|
||||
HideCursor ();
|
||||
|
||||
cprintf ( "%s\r\n\r\n", BANNER );
|
||||
if ( ! isatty ( fileno ( stdout ))) fprintf ( stdout, "%s\n\n", BANNER );
|
||||
if ( ! isatty ( fileno ( stderr ))) fprintf ( stderr, "%s\n\n", BANNER );
|
||||
|
||||
if ( argc == 1 ) {
|
||||
printHelp ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int argIndex = 1, changes = 0;
|
||||
|
||||
while ( KeyPressed ()) GetKey ();
|
||||
do {
|
||||
|
||||
argIndex = parseArgs ( argIndex, argv );
|
||||
if ( argIndex < 0 ) break;
|
||||
|
||||
char wadFileName1 [ 256 ];
|
||||
wadList *myList1 = getInputFiles ( argv [argIndex++], wadFileName1 );
|
||||
if ( myList1->IsEmpty ()) { changes = -1000; break; }
|
||||
|
||||
char wadFileName2 [ 256 ];
|
||||
wadList *myList2 = getInputFiles ( argv [argIndex++], wadFileName2 );
|
||||
if ( myList2->IsEmpty ()) { changes = -1000; break; }
|
||||
|
||||
cprintf ( "Comparing: %s and %s\r\n\n", wadFileName1, wadFileName2 );
|
||||
|
||||
char levelNames [MAX_LEVELS+1][MAX_LUMP_NAME];
|
||||
argIndex = getLevels ( argIndex, argv, levelNames, myList1, myList2 );
|
||||
|
||||
if ( levelNames [0][0] == '\0' ) {
|
||||
fprintf ( stderr, "Unable to find any valid levels in %s\n", wadFileName1 );
|
||||
break;
|
||||
}
|
||||
|
||||
int noLevels = 0;
|
||||
|
||||
do {
|
||||
|
||||
changes += ProcessLevel ( levelNames [noLevels++], myList1, myList2 );
|
||||
if ( KeyPressed () && ( GetKey () == 0x1B )) break;
|
||||
|
||||
} while ( levelNames [noLevels][0] );
|
||||
|
||||
delete myList1;
|
||||
delete myList2;
|
||||
|
||||
} while ( argv [argIndex] );
|
||||
|
||||
cprintf ( "\r\n" );
|
||||
|
||||
RestoreConsoleSettings ();
|
||||
|
||||
return changes;
|
||||
}
|
|
@ -0,0 +1,574 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: console.cpp
|
||||
// Date: 13-Aug-2000
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Screen I/O routines for ZenNode
|
||||
//
|
||||
// Copyright (c) 2000-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
// 06-??-95 Added Win32 support
|
||||
// 07-19-95 Updated command line & screen logic
|
||||
// 11-19-95 Updated command line again
|
||||
// 12-06-95 Add config & customization file support
|
||||
// 11-??-98 Added Linux support
|
||||
// 04-21-01 Modified Linux code to match Win32 console I/O behavior
|
||||
// 04-26-01 Added SIGABRT to list of 'handled' signals
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined ( __OS2__ )
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include <io.h>
|
||||
#define INCL_DOS
|
||||
#define INCL_SUB
|
||||
#include <os2.h>
|
||||
#elif defined ( __WIN32__ )
|
||||
#include <conio.h>
|
||||
#include <signal.h>
|
||||
#include <windows.h>
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
#include <memory.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include "level.hpp"
|
||||
#else
|
||||
#error This program must be compiled as a 32-bit app.
|
||||
#endif
|
||||
|
||||
#include "common.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
static UINT32 curX = 0;
|
||||
static UINT32 curY = 0;
|
||||
|
||||
UINT32 startX, startY;
|
||||
char progress [4] = { 0x7C, 0x2F, 0x2D, 0x5C };
|
||||
int progressIndex;
|
||||
|
||||
#if defined ( __OS2__ )
|
||||
|
||||
static HVIO hVio = 0;
|
||||
static VIOCURSORINFO vioco;
|
||||
static int oldAttr;
|
||||
|
||||
void SaveConsoleSettings ()
|
||||
{
|
||||
VioGetCurType ( &vioco, hVio );
|
||||
oldAttr = vioco.attr;
|
||||
vioco.attr = 0xFFFF;
|
||||
VioSetCurType ( &vioco, hVio );
|
||||
}
|
||||
|
||||
void RestoreConsoleSettings ()
|
||||
{
|
||||
vioco.attr = oldAttr;
|
||||
VioSetCurType ( &vioco, hVio );
|
||||
}
|
||||
|
||||
void GetXY ( UINT32 *x, UINT32 *y )
|
||||
{
|
||||
VioGetCurPos ( y, x, hVio );
|
||||
}
|
||||
|
||||
void GotoXY ( UINT32 x, UINT32 y )
|
||||
{
|
||||
curX = x;
|
||||
curY = y;
|
||||
VioSetCurPos ( y, x, hVio );
|
||||
}
|
||||
|
||||
UINT32 CurrentTime ()
|
||||
{
|
||||
UINT32 time;
|
||||
DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &time, 4 );
|
||||
return time;
|
||||
}
|
||||
|
||||
void Status ( char *message )
|
||||
{
|
||||
int len = strlen ( message );
|
||||
VioWrtCharStr (( BYTE * ) message, len, startY, startX, hVio );
|
||||
VioWrtNChar (( BYTE * ) " ", 80 - ( startX + len ), startY, startX + len, hVio );
|
||||
curY = startY;
|
||||
curX = startX + len;
|
||||
}
|
||||
|
||||
void GoRight ()
|
||||
{
|
||||
VioWrtNChar (( BYTE * ) "R", 1, curY, curX++, hVio );
|
||||
}
|
||||
|
||||
void GoLeft ()
|
||||
{
|
||||
VioWrtNChar (( BYTE * ) "L", 1, curY, curX - 1 , hVio );
|
||||
}
|
||||
|
||||
void Backup ()
|
||||
{
|
||||
curX--;
|
||||
}
|
||||
|
||||
void ShowDone ()
|
||||
{
|
||||
VioWrtNChar (( BYTE * ) "*", 1, curY, curX, hVio );
|
||||
}
|
||||
|
||||
void ShowProgress ()
|
||||
{
|
||||
VioWrtNChar (( BYTE * ) &progress [ progressIndex++ % SIZE ( progress )], 1, curY, curX, hVio );
|
||||
}
|
||||
|
||||
void MoveUp ( int delta )
|
||||
{
|
||||
curY -= delta;
|
||||
VioSetCurPos ( curY, 0, hVio );
|
||||
}
|
||||
|
||||
void MoveDown ( int delta )
|
||||
{
|
||||
curY += delta;
|
||||
VioSetCurPos ( curY, 0, hVio );
|
||||
}
|
||||
|
||||
#elif defined ( __WIN32__ )
|
||||
|
||||
#if defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
#define cprintf _cprintf
|
||||
#endif
|
||||
|
||||
static CONSOLE_SCREEN_BUFFER_INFO screenInfo;
|
||||
static CONSOLE_CURSOR_INFO cursorInfo;
|
||||
static BOOL oldVisible;
|
||||
|
||||
static HANDLE hOutput;
|
||||
static COORD currentPos;
|
||||
|
||||
static LARGE_INTEGER timerFrequency;
|
||||
|
||||
long WINAPI myHandler ( PEXCEPTION_POINTERS )
|
||||
{
|
||||
RestoreConsoleSettings ();
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void SignalHandler ( int )
|
||||
{
|
||||
RestoreConsoleSettings ();
|
||||
cprintf ( "\r\n" );
|
||||
exit ( -1 );
|
||||
}
|
||||
|
||||
void SaveConsoleSettings ()
|
||||
{
|
||||
hOutput = GetStdHandle ( STD_OUTPUT_HANDLE );
|
||||
GetConsoleCursorInfo ( hOutput, &cursorInfo );
|
||||
GetConsoleScreenBufferInfo ( hOutput, &screenInfo );
|
||||
oldVisible = cursorInfo.bVisible;
|
||||
SetUnhandledExceptionFilter ( myHandler );
|
||||
signal ( SIGBREAK, SignalHandler );
|
||||
signal ( SIGINT, SignalHandler );
|
||||
atexit ( RestoreConsoleSettings );
|
||||
|
||||
QueryPerformanceFrequency ( &timerFrequency );
|
||||
}
|
||||
|
||||
void RestoreConsoleSettings ()
|
||||
{
|
||||
cursorInfo.bVisible = oldVisible;
|
||||
SetConsoleCursorInfo ( hOutput, &cursorInfo );
|
||||
}
|
||||
|
||||
void HideCursor ()
|
||||
{
|
||||
CONSOLE_CURSOR_INFO info = cursorInfo;
|
||||
info.bVisible = FALSE;
|
||||
SetConsoleCursorInfo ( hOutput, &info );
|
||||
}
|
||||
|
||||
void ShowCursor ()
|
||||
{
|
||||
CONSOLE_CURSOR_INFO info = cursorInfo;
|
||||
info.bVisible = TRUE;
|
||||
SetConsoleCursorInfo ( hOutput, &info );
|
||||
}
|
||||
|
||||
int GetKey ()
|
||||
{
|
||||
int key = 0;
|
||||
UCHAR *ptr = ( UCHAR * ) &key;
|
||||
int ch = getch ();
|
||||
|
||||
if ( ch == 0xE0 ) {
|
||||
*ptr++ = 0x1B;
|
||||
*ptr++ = 0x5B;
|
||||
ch = getch ();
|
||||
switch ( ch ) {
|
||||
case 0x48 : ch = 0x41; break;
|
||||
case 0x50 : ch = 0x42; break;
|
||||
case 0x4D : ch = 0x43; break;
|
||||
case 0x4B : ch = 0x44; break;
|
||||
}
|
||||
}
|
||||
*ptr++ = ( UCHAR ) ch;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
bool KeyPressed ()
|
||||
{
|
||||
return ( kbhit () != 0 ) ? true : false;
|
||||
}
|
||||
|
||||
UINT32 CurrentTime ()
|
||||
{
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter ( &time );
|
||||
|
||||
return ( UINT32 ) ( 1000 * time.QuadPart / timerFrequency.QuadPart );
|
||||
}
|
||||
|
||||
void ClearScreen ()
|
||||
{
|
||||
DWORD dwActual;
|
||||
COORD origin;
|
||||
origin.X = 0;
|
||||
origin.Y = 0;
|
||||
FillConsoleOutputCharacter ( hOutput, ' ', screenInfo.dwSize.X * screenInfo.dwSize.Y, origin, &dwActual );
|
||||
|
||||
screenInfo.dwCursorPosition.X = 0;
|
||||
screenInfo.dwCursorPosition.Y = 0;
|
||||
}
|
||||
|
||||
void GetXY ( UINT32 *x, UINT32 *y )
|
||||
{
|
||||
GetConsoleScreenBufferInfo ( hOutput, &screenInfo );
|
||||
*x = screenInfo.dwCursorPosition.X;
|
||||
*y = screenInfo.dwCursorPosition.Y;
|
||||
}
|
||||
|
||||
void GotoXY ( UINT32 x, UINT32 y )
|
||||
{
|
||||
curX = x;
|
||||
curY = y;
|
||||
|
||||
COORD cursor;
|
||||
cursor.X = ( SHORT ) curX;
|
||||
cursor.Y = ( SHORT ) curY;
|
||||
SetConsoleCursorPosition ( hOutput, cursor );
|
||||
}
|
||||
|
||||
void MoveUp ( int delta )
|
||||
{
|
||||
GetConsoleScreenBufferInfo ( hOutput, &screenInfo );
|
||||
COORD pos;
|
||||
pos.X = ( SHORT ) 0;
|
||||
pos.Y = ( SHORT ) ( screenInfo.dwCursorPosition.Y - delta );
|
||||
SetConsoleCursorPosition ( hOutput, pos );
|
||||
}
|
||||
|
||||
void MoveDown ( int delta )
|
||||
{
|
||||
GetConsoleScreenBufferInfo ( hOutput, &screenInfo );
|
||||
COORD pos;
|
||||
pos.X = ( SHORT ) 0;
|
||||
pos.Y = ( SHORT ) ( screenInfo.dwCursorPosition.Y + delta );
|
||||
SetConsoleCursorPosition ( hOutput, pos );
|
||||
}
|
||||
|
||||
void Status ( char *message )
|
||||
{
|
||||
DWORD count;
|
||||
DWORD len = ( DWORD ) strlen ( message );
|
||||
currentPos.X = ( SHORT ) startX;
|
||||
currentPos.Y = ( SHORT ) startY;
|
||||
if ( len != 0 ) {
|
||||
WriteConsoleOutputCharacter ( hOutput, message, len, currentPos, &count );
|
||||
currentPos.X = ( SHORT ) ( currentPos.X + len );
|
||||
}
|
||||
FillConsoleOutputCharacter ( hOutput, ' ', screenInfo.dwSize.X - currentPos.X, currentPos, &count );
|
||||
}
|
||||
|
||||
void GoRight ()
|
||||
{
|
||||
DWORD count;
|
||||
WriteConsoleOutputCharacter ( hOutput, "R", 1, currentPos, &count );
|
||||
currentPos.X++;
|
||||
}
|
||||
|
||||
void GoLeft ()
|
||||
{
|
||||
DWORD count;
|
||||
currentPos.X--;
|
||||
WriteConsoleOutputCharacter ( hOutput, "L", 1, currentPos, &count );
|
||||
currentPos.X++;
|
||||
}
|
||||
|
||||
void Backup ()
|
||||
{
|
||||
currentPos.X--;
|
||||
}
|
||||
|
||||
void ShowDone ()
|
||||
{
|
||||
DWORD count;
|
||||
WriteConsoleOutputCharacter ( hOutput, "*", 1, currentPos, &count );
|
||||
}
|
||||
|
||||
void ShowProgress ()
|
||||
{
|
||||
DWORD count;
|
||||
WriteConsoleOutputCharacter ( hOutput, &progress [ progressIndex++ % SIZE ( progress )], 1, currentPos, &count );
|
||||
}
|
||||
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
|
||||
static FILE *console;
|
||||
static termios stored;
|
||||
static termios term_getch;
|
||||
static termios term_kbhit;
|
||||
static int lastChar;
|
||||
static int keyhit;
|
||||
static bool cursor_visible = true;
|
||||
|
||||
int cprintf ( const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
va_start ( args, fmt );
|
||||
|
||||
int ret = vfprintf ( console, fmt, args );
|
||||
|
||||
fflush ( console );
|
||||
|
||||
va_end ( args );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SignalHandler ( int signal )
|
||||
{
|
||||
struct sigaction sa;
|
||||
memset ( &sa, 0, sizeof ( sa ));
|
||||
sa.sa_handler = SIG_DFL;
|
||||
switch ( signal ) {
|
||||
case SIGABRT :
|
||||
RestoreConsoleSettings ();
|
||||
break;
|
||||
case SIGSEGV :
|
||||
fprintf ( stderr, "Segmentation fault" );
|
||||
case SIGINT :
|
||||
RestoreConsoleSettings ();
|
||||
printf ( "\r\n" );
|
||||
exit ( -1 );
|
||||
break;
|
||||
case SIGTSTP :
|
||||
RestoreConsoleSettings ();
|
||||
printf ( "\r\n" );
|
||||
sigaction ( SIGTSTP, &sa, NULL );
|
||||
kill ( getpid (), SIGTSTP );
|
||||
break;
|
||||
case SIGCONT :
|
||||
SaveConsoleSettings ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveConsoleSettings ()
|
||||
{
|
||||
tcgetattr ( 0, &stored );
|
||||
memcpy ( &term_getch, &stored, sizeof ( struct termios ));
|
||||
// Disable echo
|
||||
term_getch.c_lflag &= ~ECHO;
|
||||
// Disable canonical mode, and set buffer size to 1 byte
|
||||
term_getch.c_lflag &= ~ICANON;
|
||||
term_getch.c_cc[VMIN] = 1;
|
||||
|
||||
memcpy ( &term_kbhit, &term_getch, sizeof ( struct termios ));
|
||||
term_kbhit.c_cc[VTIME] = 0;
|
||||
term_kbhit.c_cc[VMIN] = 0;
|
||||
|
||||
// Create a 'console' device
|
||||
console = fopen ( "/dev/tty", "w" );
|
||||
if ( console == NULL ) {
|
||||
console = stdout;
|
||||
}
|
||||
|
||||
HideCursor ();
|
||||
|
||||
struct sigaction sa;
|
||||
memset ( &sa, 0, sizeof ( sa ));
|
||||
sa.sa_handler = SignalHandler;
|
||||
sigaction ( SIGINT, &sa, NULL );
|
||||
sigaction ( SIGABRT, &sa, NULL );
|
||||
sigaction ( SIGSEGV, &sa, NULL );
|
||||
sigaction ( SIGTSTP, &sa, NULL );
|
||||
sigaction ( SIGCONT, &sa, NULL );
|
||||
|
||||
atexit ( RestoreConsoleSettings );
|
||||
}
|
||||
|
||||
void RestoreConsoleSettings ()
|
||||
{
|
||||
if ( console != stdout ) {
|
||||
fclose ( console );
|
||||
console = stdout;
|
||||
}
|
||||
|
||||
struct sigaction sa;
|
||||
memset ( &sa, 0, sizeof ( sa ));
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction ( SIGINT, &sa, NULL );
|
||||
sigaction ( SIGABRT, &sa, NULL );
|
||||
sigaction ( SIGSEGV, &sa, NULL );
|
||||
sigaction ( SIGTSTP, &sa, NULL );
|
||||
sigaction ( SIGCONT, &sa, NULL );
|
||||
|
||||
tcsetattr ( 0, TCSANOW, &stored );
|
||||
|
||||
ShowCursor ();
|
||||
}
|
||||
|
||||
void HideCursor ()
|
||||
{
|
||||
if ( cursor_visible == true ) {
|
||||
printf ( "\033[?25l" );
|
||||
fflush ( stdout );
|
||||
cursor_visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowCursor ()
|
||||
{
|
||||
if ( cursor_visible == false ) {
|
||||
printf ( "\033[?25h" );
|
||||
fflush ( stdout );
|
||||
cursor_visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
int GetKey ()
|
||||
{
|
||||
int retVal = lastChar;
|
||||
lastChar = 0;
|
||||
|
||||
if ( keyhit == 0 ) {
|
||||
tcsetattr ( 0, TCSANOW, &term_getch );
|
||||
keyhit = read ( STDIN_FILENO, &retVal, sizeof ( retVal ));
|
||||
}
|
||||
|
||||
keyhit = 0;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool KeyPressed ()
|
||||
{
|
||||
if ( keyhit == 0 ) {
|
||||
tcsetattr ( 0, TCSANOW, &term_kbhit );
|
||||
keyhit = read ( STDIN_FILENO, &lastChar, sizeof ( lastChar ));
|
||||
}
|
||||
|
||||
return ( keyhit != 0 ) ? true : false;
|
||||
}
|
||||
|
||||
UINT32 CurrentTime ()
|
||||
{
|
||||
timeval time;
|
||||
gettimeofday ( &time, NULL );
|
||||
return ( UINT32 ) (( time.tv_sec * 1000 ) + ( time.tv_usec / 1000 ));
|
||||
}
|
||||
|
||||
void ClearScreen ()
|
||||
{
|
||||
printf ( "\033[2J" );
|
||||
fflush ( stdout );
|
||||
}
|
||||
|
||||
void GetXY ( UINT32 *x, UINT32 *y )
|
||||
{
|
||||
*x = MAX_LUMP_NAME + 5;
|
||||
*y = 0;
|
||||
}
|
||||
|
||||
void GotoXY ( UINT32 x, UINT32 y )
|
||||
{
|
||||
// fprintf ( console, "\033[%d;%dH", y, x );
|
||||
fprintf ( console, "\033[%dG", x );
|
||||
fflush ( console );
|
||||
curX = x;
|
||||
curY = y;
|
||||
}
|
||||
|
||||
void Status ( char *message )
|
||||
{
|
||||
fprintf ( console, "\033[%dG%s\033[K", startX, message );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void GoRight ()
|
||||
{
|
||||
fprintf ( console, "R" );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void GoLeft ()
|
||||
{
|
||||
fprintf ( console, "\033[DL" );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void Backup ()
|
||||
{
|
||||
fprintf ( console, "\033[D" );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void ShowDone ()
|
||||
{
|
||||
fprintf ( console, "*\033[D" );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void ShowProgress ()
|
||||
{
|
||||
fprintf ( console, "%c\033[D", progress [ progressIndex++ % SIZE ( progress )] );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void MoveUp ( int delta )
|
||||
{
|
||||
fprintf ( console, "\033[%dA", delta );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
void MoveDown ( int delta )
|
||||
{
|
||||
fprintf ( console, "\033[%dB", delta );
|
||||
fflush ( console );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: console.hpp
|
||||
// Date: 01-Jun-2002
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Copyright (c) 1998-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef CONSOLE_HPP_
|
||||
#define CONSOLE_HPP_
|
||||
|
||||
#if defined ( __OS2__ ) || defined ( __WIN32__ )
|
||||
|
||||
#if defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
#define cprintf _cprintf
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
|
||||
#define stricmp strcasecmp
|
||||
|
||||
extern int cprintf ( const char *, ... );
|
||||
|
||||
#endif
|
||||
|
||||
void SaveConsoleSettings ();
|
||||
void RestoreConsoleSettings ();
|
||||
|
||||
void HideCursor ();
|
||||
void ShowCursor ();
|
||||
|
||||
int GetKey ();
|
||||
bool KeyPressed ();
|
||||
|
||||
UINT32 CurrentTime ();
|
||||
|
||||
void ClearScreen ();
|
||||
|
||||
extern UINT32 startX, startY;
|
||||
|
||||
void GetXY ( UINT32 *x, UINT32 *y );
|
||||
void GotoXY ( UINT32 x, UINT32 y );
|
||||
void MoveUp ( int delta );
|
||||
void MoveDown ( int delta );
|
||||
void PutXY ( UINT32 x, UINT32 y, char *ptr, int length );
|
||||
void Put ( char *ptr, int length );
|
||||
|
||||
// ----- External Functions Required by ZenNode -----
|
||||
|
||||
void Status ( char *message );
|
||||
void GoRight ();
|
||||
void GoLeft ();
|
||||
void Backup ();
|
||||
void ShowDone ();
|
||||
void ShowProgress ();
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: geometry.hpp
|
||||
// Date: 26-October-1994
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef GEOMETRY_HPP_
|
||||
#define GEOMETRY_HPP_
|
||||
|
||||
#if ! defined ( COMMON_HPP_ )
|
||||
#include "common.hpp"
|
||||
#endif
|
||||
|
||||
struct sPoint;
|
||||
struct sRectangle;
|
||||
|
||||
struct sPoint {
|
||||
long x;
|
||||
long y;
|
||||
sPoint () { x = 0; y = 0; }
|
||||
sPoint ( long _x, long _y ) { x = _x; y = _y; }
|
||||
bool isInside ( const sRectangle & ) const;
|
||||
bool operator == ( const sPoint &o ) const { return ( x == o.x ) && ( y == o.y ); }
|
||||
bool operator != ( const sPoint &o ) const { return ( x != o.x ) || ( y != o.y ); }
|
||||
};
|
||||
|
||||
struct sLine {
|
||||
sPoint start;
|
||||
sPoint end;
|
||||
sLine () : start (), end () {}
|
||||
sLine ( const sPoint &s, const sPoint &e ) { start = s; end = e; }
|
||||
int rise () const { return end.y - start.y; }
|
||||
int run () const { return end.x - start.x; }
|
||||
float slope () const { return rise () / ( float ) run (); }
|
||||
bool endMatches ( const sLine & ) const;
|
||||
bool isInside ( const sRectangle & ) const;
|
||||
bool intersects ( const sRectangle & ) const;
|
||||
bool intersects ( const sLine & ) const;
|
||||
};
|
||||
|
||||
struct sRectangle {
|
||||
int xLeft, xRight;
|
||||
int yTop, yBottom;
|
||||
sRectangle ();
|
||||
sRectangle ( long, long, long, long );
|
||||
sRectangle ( const sPoint &, const sPoint & );
|
||||
void include ( const sPoint & );
|
||||
void include ( const sRectangle & );
|
||||
long left () const { return xLeft; }
|
||||
long right () const { return xRight; }
|
||||
long top () const { return yTop; }
|
||||
long bottom () const { return yBottom; }
|
||||
long width () const { return xRight - xLeft; }
|
||||
long height () const { return yTop - yBottom; }
|
||||
sPoint center () const { return sPoint (( xLeft + xRight ) / 2, ( yTop + yBottom ) / 2 ); }
|
||||
sPoint tl () const { return sPoint ( xLeft, yTop ); }
|
||||
sPoint bl () const { return sPoint ( xLeft, yBottom ); }
|
||||
sPoint tr () const { return sPoint ( xRight, yTop ); }
|
||||
sPoint br () const { return sPoint ( xRight, yBottom ); }
|
||||
bool isInside ( const sRectangle & ) const;
|
||||
bool intersects ( const sRectangle & ) const;
|
||||
};
|
||||
|
||||
inline sRectangle::sRectangle ()
|
||||
{
|
||||
xLeft = yTop = xRight = yBottom = 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,139 @@
|
|||
# ZenNode makefile for Linux
|
||||
|
||||
CC = g++
|
||||
CFLAGS += -g -O -fstrength-reduce -fno-rtti
|
||||
CFLAGS += -fomit-frame-pointer -foptimize-sibling-calls
|
||||
#CFLAGS += -fbranch-probabilities
|
||||
#CFLAGS += -fprofile-arcs
|
||||
WARNINGS = -Wall -Wno-format -Wstrict-prototypes -Wmissing-prototypes -Winline
|
||||
#CC = /opt/intel/compiler60/ia32/bin/icc
|
||||
#CFLAGS = -g -O3
|
||||
INCLUDES = -I../DOOM -I../common
|
||||
TARGETS = ZenNode bspdiff bspinfo compare
|
||||
|
||||
CFLAGS += -D__LINUX__
|
||||
|
||||
ifdef WIN32
|
||||
CFLAGS += -D__WIN32__
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -DDEBUG
|
||||
LOGGER = ../common/logger/logger.o ../common/logger/string.o
|
||||
CFLAGS += -fexceptions
|
||||
LOGGER += ../common/logger/linux-logger.o
|
||||
LIBS += -lpthread -lrt
|
||||
endif
|
||||
|
||||
.cpp.o:
|
||||
$(CC) -c $(CFLAGS) $(WARNINGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
.SUFFIXES: .cpp .o
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
depend: clean
|
||||
|
||||
clean:
|
||||
rm -rf {.,../DOOM/,../common/logger}/{*.o,*~} $(TARGETS)
|
||||
|
||||
ZenNode: ZenMain.o ZenNode.o ZenReject.o ZenRMB.o blockmap.o console.o ../DOOM/wad.o ../DOOM/level.o $(LOGGER)
|
||||
$(CC) $(LIBS) -o $@ $^
|
||||
|
||||
bspdiff: bspdiff.o console.o ../DOOM/wad.o ../DOOM/level.o $(LOGGER)
|
||||
$(CC) $(LIBS) -o $@ $^
|
||||
|
||||
bspinfo: bspinfo.o console.o ../DOOM/wad.o ../DOOM/level.o $(LOGGER)
|
||||
$(CC) $(LIBS) -o $@ $^
|
||||
|
||||
compare: compare.o console.o ../DOOM/wad.o ../DOOM/level.o $(LOGGER)
|
||||
$(CC) $(LIBS) -o $@ $^
|
||||
|
||||
ZenReject.o: \
|
||||
ZenReject.cpp \
|
||||
ZenReject-util.cpp \
|
||||
../common/common.hpp \
|
||||
../DOOM/level.hpp \
|
||||
ZenNode.hpp \
|
||||
console.hpp \
|
||||
geometry.hpp
|
||||
|
||||
ZenNode.o: \
|
||||
ZenNode.cpp \
|
||||
../common/common.hpp \
|
||||
../common/logger.hpp \
|
||||
../DOOM/level.hpp \
|
||||
ZenNode.hpp \
|
||||
console.hpp
|
||||
|
||||
ZenMain.o: \
|
||||
ZenMain.cpp \
|
||||
../common/common.hpp \
|
||||
../common/logger.hpp \
|
||||
../DOOM/wad.hpp \
|
||||
../DOOM/level.hpp \
|
||||
console.hpp \
|
||||
ZenNode.hpp
|
||||
|
||||
ZenReject.o: \
|
||||
ZenReject.cpp \
|
||||
../common/common.hpp \
|
||||
../DOOM/level.hpp \
|
||||
ZenNode.hpp \
|
||||
console.hpp \
|
||||
geometry.hpp
|
||||
|
||||
ZenRMB.o: \
|
||||
ZenRMB.cpp \
|
||||
../common/common.hpp \
|
||||
../DOOM/level.hpp \
|
||||
ZenNode.hpp
|
||||
|
||||
blockmap.o: \
|
||||
blockmap.cpp \
|
||||
../common/common.hpp \
|
||||
../DOOM/level.hpp \
|
||||
ZenNode.hpp
|
||||
|
||||
console.o: \
|
||||
console.cpp \
|
||||
../DOOM/level.hpp \
|
||||
../common/common.hpp \
|
||||
console.hpp \
|
||||
|
||||
../DOOM/wad.o: \
|
||||
../DOOM/wad.cpp \
|
||||
../common/common.hpp \
|
||||
../DOOM/wad.hpp \
|
||||
../DOOM/level.hpp
|
||||
|
||||
../DOOM/level.o: \
|
||||
../DOOM/level.cpp \
|
||||
../common/common.hpp \
|
||||
../common/logger.hpp \
|
||||
../DOOM/wad.hpp \
|
||||
../DOOM/level.hpp
|
||||
|
||||
bspdiff.o: \
|
||||
bspdiff.cpp \
|
||||
../common/common.hpp \
|
||||
../common/logger.hpp \
|
||||
../DOOM/wad.hpp \
|
||||
../DOOM/level.hpp \
|
||||
console.hpp
|
||||
|
||||
bspinfo.o: \
|
||||
bspinfo.cpp \
|
||||
../common/common.hpp \
|
||||
../common/logger.hpp \
|
||||
../DOOM/wad.hpp \
|
||||
../DOOM/level.hpp \
|
||||
console.hpp
|
||||
|
||||
compare.o: \
|
||||
compare.cpp \
|
||||
../common/common.hpp \
|
||||
../common/logger.hpp \
|
||||
../DOOM/wad.hpp \
|
||||
../DOOM/level.hpp \
|
||||
console.hpp
|
|
@ -0,0 +1,258 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: common.hpp
|
||||
// Date:
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Copyright (c) 1994-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef COMMON_HPP_
|
||||
#define COMMON_HPP_
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Generic definitions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifdef UNREFERENCED_PARAMETER
|
||||
#undef UNREFERENCED_PARAMETER
|
||||
#endif
|
||||
|
||||
#if defined ( _MSC_VER )
|
||||
#define UNREFERENCED_PARAMETER(x) x
|
||||
#else
|
||||
#define UNREFERENCED_PARAMETER(x)
|
||||
#endif
|
||||
|
||||
#define OFFSET_OF(t,x) (( size_t ) & (( t * ) 0 )->( x ))
|
||||
#define SIZE(x) ( sizeof ( x ) / sizeof (( x )[0] ))
|
||||
#define EVER ;;
|
||||
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
|
||||
typedef unsigned char UINT8, UCHAR;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
|
||||
typedef long long INT64;
|
||||
typedef unsigned long long UINT64;
|
||||
|
||||
#else
|
||||
|
||||
typedef __int64 INT64;
|
||||
typedef unsigned __int64 UINT64;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined ( __WIN32__ ) || defined ( __AMIGAOS__ )
|
||||
|
||||
// Undo any previos definitions
|
||||
#define BIG_ENDIAN 1234
|
||||
#define LITTLE_ENDIAN 4321
|
||||
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
|
||||
#else
|
||||
|
||||
// Use the environments endian definitions
|
||||
#undef __USE_BSD
|
||||
#define __USE_BSD
|
||||
#include <endian.h>
|
||||
|
||||
#endif
|
||||
|
||||
typedef int (*QSORT_FUNC) ( const void *, const void * );
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
template < class T > inline void swap ( T &item1, T &item2 )
|
||||
{
|
||||
T temp = item1;
|
||||
item1 = item2;
|
||||
item2 = temp;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Platform specific definitions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined ( __OS2__ ) || defined ( __WIN32__ )
|
||||
|
||||
#define SEPERATOR '\\'
|
||||
#define DEFAULT_CHAR 'û'
|
||||
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
|
||||
#define SEPERATOR '/'
|
||||
#define DEFAULT_CHAR '*'
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Compiler specific definitions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined ( __BORLANDC__ )
|
||||
|
||||
#if defined ( __BCPLUSPLUS__ ) || defined ( __TCPLUSPLUS__ )
|
||||
#undef NULL
|
||||
#define NULL ( void * ) 0
|
||||
#endif
|
||||
|
||||
#if (( __BORLANDC__ < 0x0500 ) || defined ( __OS2__ ))
|
||||
|
||||
// Fake out ANSI definitions for deficient compilers
|
||||
#define for if (0); else for
|
||||
|
||||
enum { false, true };
|
||||
class bool {
|
||||
int value;
|
||||
public:
|
||||
operator = ( int x ) { value = x ? true : false; }
|
||||
bool operator ! () { return value; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class T> inline const T &min ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t2 : t1;
|
||||
}
|
||||
|
||||
template <class T> inline const T &max ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t1 : t2;
|
||||
}
|
||||
|
||||
#elif defined ( _MSC_VER )
|
||||
|
||||
#undef NULL
|
||||
#define NULL 0L
|
||||
|
||||
#define MAXPATH _MAX_PATH
|
||||
#define MAXDRIVE _MAX_DRIVE
|
||||
#define MAXDIR _MAX_DIR
|
||||
#define MAXFNAME _MAX_FNAME
|
||||
#define MAXEXT _MAX_EXT
|
||||
|
||||
#if ( _MSC_VER < 1300 )
|
||||
|
||||
// Fake out ANSI definitions for deficient compilers
|
||||
#define for if (0); else for
|
||||
|
||||
#pragma warning ( disable: 4127 ) // C4127: conditional expression is constant
|
||||
|
||||
#endif
|
||||
|
||||
#pragma warning ( disable: 4244 ) // C4244: 'xyz' conversion from 'xxx' to 'yyy', possible loss of data
|
||||
#pragma warning( disable : 4290 ) // C4290: C++ exception specification ignored...
|
||||
#pragma warning ( disable: 4514 ) // C4514: 'xyz' unreferenced inline function has been removed
|
||||
|
||||
template <class T> inline const T &min ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t2 : t1;
|
||||
}
|
||||
|
||||
template <class T> inline const T &max ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t1 : t2;
|
||||
}
|
||||
|
||||
#if ( _MSC_VER >= 1300 )
|
||||
extern char *strndup ( const char *string, size_t max );
|
||||
#endif
|
||||
|
||||
#elif defined ( __WATCOMC__ )
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
template <class T> inline const T &min ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t2 : t1;
|
||||
}
|
||||
|
||||
template <class T> inline const T &max ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t1 : t2;
|
||||
}
|
||||
|
||||
#elif defined ( __GNUC__ ) || defined ( __INTEL_COMPILER )
|
||||
|
||||
#define MAXPATH FILENAME_MAX
|
||||
#define MAXDRIVE FILENAME_MAX
|
||||
#define MAXDIR FILENAME_MAX
|
||||
#define MAXFNAME FILENAME_MAX
|
||||
#define MAXEXT FILENAME_MAX
|
||||
|
||||
#define O_BINARY 0
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#define strnicmp strncasecmp
|
||||
|
||||
template <class T> inline const T &min ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t2 : t1;
|
||||
}
|
||||
|
||||
template <class T> inline const T &max ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t1 : t2;
|
||||
}
|
||||
|
||||
#elif defined ( __AMIGAOS__ )
|
||||
|
||||
// Fake out ANSI definitions for deficient compilers
|
||||
#define for if (0); else for
|
||||
|
||||
enum { false, true };
|
||||
class bool {
|
||||
int value;
|
||||
public:
|
||||
operator = ( int x ) { value = x ? true : false; }
|
||||
bool operator ! () { return value; }
|
||||
};
|
||||
|
||||
template <class T> inline const T &min ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t2 : t1;
|
||||
}
|
||||
|
||||
template <class T> inline const T &max ( const T &t1, const T &t2 )
|
||||
{
|
||||
return ( t1 > t2 ) ? t1 : t2;
|
||||
}
|
||||
|
||||
extern char *strdup ( const char *string );
|
||||
extern char *strndup ( const char *string, size_t max );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,185 @@
|
|||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// File: logger.hpp
|
||||
// Date: 15-Apr-1998
|
||||
// Programmer: Marc Rousseau
|
||||
//
|
||||
// Description: Error Logger object header
|
||||
//
|
||||
// Copyright (c) 1998-2004 Marc Rousseau, All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// Revision History:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef LOGGER_HPP_
|
||||
#define LOGGER_HPP_
|
||||
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
#ifdef ASSERT
|
||||
#undef ASSERT
|
||||
#endif
|
||||
|
||||
#if defined ( DEBUG )
|
||||
|
||||
struct LOG_FLAGS {
|
||||
bool FunctionEntry;
|
||||
};
|
||||
|
||||
extern LOG_FLAGS g_LogFlags;
|
||||
|
||||
#define FUNCTION_ENTRY(t,f,l) \
|
||||
void *l_pThis = ( void * ) t; \
|
||||
char *l_FnName = f; \
|
||||
bool l_log = ( g_LogFlags.FunctionEntry == l ) ? true : false; \
|
||||
if ( l_log && g_LogFlags.FunctionEntry ) { \
|
||||
DBG_MINOR_TRACE2 ( l_FnName, l_pThis, "Function entered" ); \
|
||||
}
|
||||
|
||||
#define ASSERT(x) (( ! ( x )) ? dbg_Assert ( dbg_FileName, __LINE__, l_FnName, l_pThis, #x ), 1 : 0 )
|
||||
#define ASSERT_BOOL(x) ASSERT ( x )
|
||||
|
||||
#else
|
||||
|
||||
#if defined ( _MSC_VER )
|
||||
#pragma warning ( disable: 4127 ) // C4127: conditional expression is constant
|
||||
#endif
|
||||
|
||||
#define FUNCTION_ENTRY(t,f,l)
|
||||
#define ASSERT(x)
|
||||
#define ASSERT_BOOL(x) 0
|
||||
|
||||
#endif
|
||||
|
||||
#define TRACE(x) DBG_MAJOR_TRACE2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define EVENT(x) DBG_MINOR_EVENT2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define MINOR_EVENT(x) DBG_MINOR_EVENT2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define MAJOR_EVENT(x) DBG_MAJOR_EVENT2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define STATUS(x) DBG_STATUS2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define WARNING(x) DBG_WARNING2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define ERROR(x) DBG_ERROR2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
#define FATAL(x) DBG_FATAL2 ( l_FnName, l_pThis, ( const char * ) x )
|
||||
|
||||
#if ! defined ( DEBUG )
|
||||
|
||||
#define DBG_REGISTER(x)
|
||||
#define DBG_STRING(x) ""
|
||||
#define DBG_MINOR_TRACE(f,t,x)
|
||||
#define DBG_MINOR_TRACE2(f,t,x)
|
||||
#define DBG_MAJOR_TRACE(f,t,x)
|
||||
#define DBG_MAJOR_TRACE2(f,t,x)
|
||||
#define DBG_MINOR_EVENT(f,t,x)
|
||||
#define DBG_MINOR_EVENT2(f,t,x)
|
||||
#define DBG_MAJOR_EVENT(f,t,x)
|
||||
#define DBG_MAJOR_EVENT2(f,t,x)
|
||||
#define DBG_STATUS(f,t,x)
|
||||
#define DBG_STATUS2(f,t,x)
|
||||
#define DBG_WARNING(f,t,x)
|
||||
#define DBG_WARNING2(f,t,x)
|
||||
#define DBG_ERROR(f,t,x)
|
||||
#define DBG_ERROR2(f,t,x)
|
||||
#define DBG_FATAL(f,t,x)
|
||||
#define DBG_FATAL2(f,t,x)
|
||||
#define DBG_ASSERT(f,t,x) 0
|
||||
|
||||
#else
|
||||
|
||||
#define DBG_REGISTER(x) static int dbg_FileName = dbg_RegisterFile ( x );
|
||||
#define DBG_STRING(x) x
|
||||
#define DBG_MINOR_TRACE(f,t,x) dbg_Record ( _MINOR_TRACE_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_MINOR_TRACE2(f,t,x) dbg_Record ( _MINOR_TRACE_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_MAJOR_TRACE(f,t,x) dbg_Record ( _MAJOR_TRACE_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_MAJOR_TRACE2(f,t,x) dbg_Record ( _MAJOR_TRACE_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_MINOR_EVENT(f,t,x) dbg_Record ( _MINOR_EVENT_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_MINOR_EVENT2(f,t,x) dbg_Record ( _MINOR_EVENT_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_MAJOR_EVENT(f,t,x) dbg_Record ( _MAJOR_EVENT_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_MAJOR_EVENT2(f,t,x) dbg_Record ( _MAJOR_EVENT_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_STATUS(f,t,x) dbg_Record ( _STATUS_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_STATUS2(f,t,x) dbg_Record ( _STATUS_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_WARNING(f,t,x) dbg_Record ( _WARNING_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_WARNING2(f,t,x) dbg_Record ( _WARNING_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_ERROR(f,t,x) dbg_Record ( _ERROR_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_ERROR2(f,t,x) dbg_Record ( _ERROR_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_FATAL(f,t,x) dbg_Record ( _FATAL_, dbg_FileName, __LINE__, f, t, x )
|
||||
#define DBG_FATAL2(f,t,x) dbg_Record ( _FATAL_, dbg_FileName, __LINE__, f, t, dbg_Stream () << x ), dbg_Stream ().flush ()
|
||||
#define DBG_ASSERT(f,t,x) (( ! ( x )) ? dbg_Assert ( dbg_FileName, __LINE__, f, t, #x ), 1 : 0 )
|
||||
|
||||
enum eLOG_TYPE {
|
||||
_MINOR_TRACE_,
|
||||
_MAJOR_TRACE_,
|
||||
_MINOR_EVENT_,
|
||||
_MAJOR_EVENT_,
|
||||
_STATUS_,
|
||||
_WARNING_,
|
||||
_ERROR_,
|
||||
_FATAL_,
|
||||
LOG_TYPE_MAX
|
||||
};
|
||||
|
||||
class dbgString {
|
||||
|
||||
friend dbgString &hex ( dbgString & );
|
||||
friend dbgString &dec ( dbgString & );
|
||||
|
||||
int m_Base;
|
||||
bool m_OwnBuffer;
|
||||
char *m_Ptr;
|
||||
char *m_Buffer;
|
||||
|
||||
public:
|
||||
|
||||
dbgString ( char * );
|
||||
|
||||
operator const char * ();
|
||||
void flush ();
|
||||
|
||||
dbgString &operator << ( const char * );
|
||||
dbgString &operator << ( char );
|
||||
dbgString &operator << ( unsigned char );
|
||||
dbgString &operator << ( short );
|
||||
dbgString &operator << ( unsigned short );
|
||||
dbgString &operator << ( int );
|
||||
dbgString &operator << ( unsigned int );
|
||||
dbgString &operator << ( long );
|
||||
dbgString &operator << ( unsigned long );
|
||||
/*
|
||||
dbgString &operator << ( __int64 );
|
||||
dbgString &operator << ( unsigned __int64 );
|
||||
*/
|
||||
dbgString &operator << ( double );
|
||||
dbgString &operator << ( void * );
|
||||
dbgString &operator << ( dbgString &(*f) ( dbgString & ));
|
||||
|
||||
};
|
||||
|
||||
dbgString &hex ( dbgString & );
|
||||
dbgString &dec ( dbgString & );
|
||||
|
||||
extern "C" {
|
||||
|
||||
dbgString &dbg_Stream ();
|
||||
int dbg_RegisterFile ( const char * );
|
||||
void dbg_Assert ( int, int, const char * , void *, const char * );
|
||||
void dbg_Record ( int, int, int, const char *, void *, const char * );
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue