├── common
├── test.h
├── threads.h
├── trilib.h
├── scriplib.h
├── polylib.h
├── lbmlib.h
├── wadlib.h
├── mathlib.h
├── mathlib.c
├── cmdlib.h
├── scriplib.c
├── common.vcxproj
├── trilib.c
├── threads.c
├── bspfile.h
├── wadlib.c
└── polylib.c
├── xcode
├── light
│ ├── light
│ │ └── .gitignore
│ └── light.xcodeproj
│ │ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── fabiensanglard.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcuserdata
│ │ └── fabiensanglard.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── light.xcscheme
├── qbsp
│ └── qbsp
│ │ └── .gitignore
├── qcc
│ ├── qcc
│ │ └── .gitignore
│ └── qcc.xcodeproj
│ │ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── fabiensanglard.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcuserdata
│ │ └── fabiensanglard.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── qcc.xcscheme
└── vis
│ └── vis
│ └── .gitignore
├── qc
├── progs.src
├── sprites.qc
├── progdefs.h
├── spectate.qc
├── server.qc
├── buttons.qc
├── subs.qc
├── combat.qc
└── plats.qc
├── README
├── light
├── threads.h
├── entities.h
├── light.h
├── threads.c
├── light.c
├── light.vcxproj
├── trace.c
└── entities.c
├── qbsp
├── nodraw.c
├── map.h
├── qbsp.vcxproj
├── outside.c
├── merge.c
└── bsp5.h
├── qbsp.sln
├── maps
└── simple.map
├── vis
├── vis.h
├── soundpvs.c
└── vis.vcxproj
├── qcc
├── pr_comp.h
└── qcc.vcxproj
└── comments
└── text.txt
/common/test.h:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/xcode/light/light/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/xcode/qbsp/qbsp/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/xcode/qcc/qcc/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/xcode/vis/vis/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/xcode/qcc/qcc.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/xcode/light/light.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/qc/progs.src:
--------------------------------------------------------------------------------
1 | ./qwprogs.dat
2 |
3 | defs.qc
4 | subs.qc
5 | combat.qc
6 | items.qc
7 | weapons.qc
8 | world.qc
9 | client.qc
10 | spectate.qc
11 | player.qc
12 | doors.qc
13 | buttons.qc
14 | triggers.qc
15 | plats.qc
16 | misc.qc
17 |
18 | server.qc
19 |
--------------------------------------------------------------------------------
/xcode/qcc/qcc.xcodeproj/project.xcworkspace/xcuserdata/fabiensanglard.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fabiensanglard/Quake--QBSP-and-VIS/HEAD/xcode/qcc/qcc.xcodeproj/project.xcworkspace/xcuserdata/fabiensanglard.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/xcode/light/light.xcodeproj/project.xcworkspace/xcuserdata/fabiensanglard.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fabiensanglard/Quake--QBSP-and-VIS/HEAD/xcode/light/light.xcodeproj/project.xcworkspace/xcuserdata/fabiensanglard.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This is the source code of qbsp and vis: Quake preprocessing tools.
2 |
3 | They have been modified in order to trace the portal building system
4 | and the PVS building systems.
5 |
6 | Quake 1 maps have been released as GPL by John Romero on October 12, 2006 (In honour of Quake's 10th year).
7 |
8 | You can also use Q3Radiant: It features a built-in viewprt Portal Viewer that work on Quake1 files.
9 |
10 |
--------------------------------------------------------------------------------
/xcode/qcc/qcc.xcodeproj/xcuserdata/fabiensanglard.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | qcc.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 2DF5071F14C8DF20000A6C0D
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/xcode/light/light.xcodeproj/xcuserdata/fabiensanglard.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | light.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 2DF506CD14C8DDC3000A6C0D
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/common/threads.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | extern int numthreads;
22 |
23 | int GetThreadWork (void);
24 | void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int));
25 | void ThreadLock (void);
26 | void ThreadUnlock (void);
27 |
28 |
--------------------------------------------------------------------------------
/common/trilib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | //
21 | // trilib.h: header file for loading triangles from an Alias triangle file
22 | //
23 | #define MAXTRIANGLES 2048
24 |
25 | typedef struct {
26 | vec3_t verts[3];
27 | } triangle_t;
28 |
29 | void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles);
30 |
31 |
--------------------------------------------------------------------------------
/light/threads.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #ifdef __alpha
22 | #include
23 | extern pthread_mutex_t *my_mutex;
24 | #define LOCK pthread_mutex_lock (my_mutex)
25 | #define UNLOCK pthread_mutex_unlock (my_mutex)
26 | #else
27 | #define LOCK
28 | #define UNLOCK
29 | #endif
30 |
31 | extern int numthreads;
32 |
33 | typedef void (threadfunc_t) (void *);
34 |
35 | void InitThreads (void);
36 | void RunThreadsOn ( threadfunc_t func );
37 |
--------------------------------------------------------------------------------
/common/scriplib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // scriplib.h
21 |
22 | #ifndef __CMDLIB__
23 | #include "cmdlib.h"
24 | #endif
25 |
26 | #define MAXTOKEN 128
27 |
28 | extern char token[MAXTOKEN];
29 | extern char *scriptbuffer,*script_p,*scriptend_p;
30 | extern int grabbed;
31 | extern int scriptline;
32 | extern qboolean endofscript;
33 |
34 |
35 | void LoadScriptFile (char *filename);
36 | qboolean GetToken (qboolean crossline);
37 | void UnGetToken (void);
38 | qboolean TokenAvailable (void);
39 |
40 |
41 |
--------------------------------------------------------------------------------
/qc/sprites.qc:
--------------------------------------------------------------------------------
1 | /*
2 | sprites.qc
3 |
4 | sprite definitions
5 |
6 | Copyright (C) 1996-1997 Id Software, Inc.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 |
17 | See the GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to:
21 |
22 | Free Software Foundation, Inc.
23 | 59 Temple Place - Suite 330
24 | Boston, MA 02111-1307, USA
25 |
26 | */
27 |
28 | // these are the only sprites still in the game...
29 |
30 | $spritename s_explod
31 | $type vp_parallel
32 | $load /raid/quake/id1/gfx/sprites/explod03.lbm
33 | $frame 24 24 56 56
34 | $frame 120 24 56 56
35 | $frame 216 24 56 56
36 | $frame 24 88 56 56
37 | $frame 120 88 56 56
38 | $frame 216 88 56 56
39 |
40 |
41 | $spritename s_bubble
42 | $type vp_parallel
43 | $load /raid/quake/id1/gfx/sprites/bubble.lbm
44 | $frame 16 16 16 16
45 | $frame 40 16 16 16
46 |
47 |
48 | $spritename s_light
49 | $type vp_parallel
50 | $load /raid/quake/id1/gfx/sprites/light.lbm
51 | $frame 104 32 32 32
52 |
53 |
--------------------------------------------------------------------------------
/qbsp/nodraw.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #include "bsp5.h"
22 |
23 | void Draw_ClearBounds (void)
24 | {
25 | }
26 |
27 | void Draw_AddToBounds (vec3_t v)
28 | {
29 | }
30 |
31 | void Draw_DrawFace (face_t *f)
32 | {
33 | }
34 |
35 | void Draw_ClearWindow (void)
36 | {
37 | }
38 |
39 | void Draw_SetRed (void)
40 | {
41 | }
42 |
43 | void Draw_SetGrey (void)
44 | {
45 | }
46 |
47 | void Draw_SetBlack (void)
48 | {
49 | }
50 |
51 | void DrawPoint (vec3_t v)
52 | {
53 | }
54 |
55 | void DrawLeaf (node_t *l, int color)
56 | {
57 | }
58 |
59 | void DrawBrush (brush_t *b)
60 | {
61 | }
62 |
63 | void DrawWinding (winding_t *w)
64 | {
65 | }
66 |
67 | void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
68 | {
69 | }
70 |
71 | void DrawPortal (portal_t *portal)
72 | {
73 | }
74 |
--------------------------------------------------------------------------------
/common/polylib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | typedef struct
22 | {
23 | int numpoints;
24 | vec3_t p[4]; // variable sized
25 | } winding_t;
26 |
27 | #define MAX_POINTS_ON_WINDING 64
28 |
29 | #define ON_EPSILON 0.1
30 |
31 | winding_t *AllocWinding (int points);
32 | vec_t WindingArea (winding_t *w);
33 | void WindingCenter (winding_t *w, vec3_t center);
34 | void ClipWinding (winding_t *in, vec3_t normal, vec_t dist,
35 | winding_t **front, winding_t **back);
36 | winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist);
37 | winding_t *CopyWinding (winding_t *w);
38 | winding_t *BaseWindingForPlane (vec3_t normal, float dist);
39 | void CheckWinding (winding_t *w);
40 | void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist);
41 | void RemoveColinearPoints (winding_t *w);
42 |
--------------------------------------------------------------------------------
/common/lbmlib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // lbmlib.h
21 |
22 | typedef unsigned char UBYTE;
23 | typedef short WORD;
24 | typedef unsigned short UWORD;
25 | typedef long LONG;
26 |
27 | typedef enum
28 | {
29 | ms_none,
30 | ms_mask,
31 | ms_transcolor,
32 | ms_lasso
33 | } mask_t;
34 |
35 | typedef enum
36 | {
37 | cm_none,
38 | cm_rle1
39 | } compress_t;
40 |
41 | typedef struct
42 | {
43 | UWORD w,h;
44 | WORD x,y;
45 | UBYTE nPlanes;
46 | UBYTE masking;
47 | UBYTE compression;
48 | UBYTE pad1;
49 | UWORD transparentColor;
50 | UBYTE xAspect,yAspect;
51 | WORD pageWidth,pageHeight;
52 | } bmhd_t;
53 |
54 | extern bmhd_t bmhd; // will be in native byte order
55 |
56 |
57 | void LoadLBM (char *filename, byte **picture, byte **palette);
58 |
59 | void WriteLBMfile (char *filename, byte *data, int width, int height
60 | , byte *palette);
61 |
62 |
--------------------------------------------------------------------------------
/light/entities.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #define DEFAULTLIGHTLEVEL 300
22 |
23 | typedef struct epair_s
24 | {
25 | struct epair_s *next;
26 | char key[MAX_KEY];
27 | char value[MAX_VALUE];
28 | } epair_t;
29 |
30 | typedef struct entity_s
31 | {
32 | char classname[64];
33 | vec3_t origin;
34 | float angle;
35 | int light;
36 | int style;
37 | char target[32];
38 | char targetname[32];
39 | struct epair_s *epairs;
40 | struct entity_s *targetent;
41 | } entity_t;
42 |
43 | extern entity_t entities[MAX_MAP_ENTITIES];
44 | extern int num_entities;
45 |
46 | char *ValueForKey (entity_t *ent, char *key);
47 | void SetKeyValue (entity_t *ent, char *key, char *value);
48 | float FloatForKey (entity_t *ent, char *key);
49 | void GetVectorForKey (entity_t *ent, char *key, vec3_t vec);
50 |
51 | void LoadEntities (void);
52 | void WriteEntitiesToString (void);
53 |
--------------------------------------------------------------------------------
/light/light.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #include "cmdlib.h"
22 | #include "mathlib.h"
23 | #include "bspfile.h"
24 | #include "entities.h"
25 | #include "threads.h"
26 |
27 | #define ON_EPSILON 0.1
28 |
29 | #define MAXLIGHTS 1024
30 |
31 | void LoadNodes (char *file);
32 | qboolean TestLine (vec3_t start, vec3_t stop);
33 |
34 | void LightFace (int surfnum);
35 | void LightLeaf (dleaf_t *leaf);
36 |
37 | void MakeTnodes (dmodel_t *bm);
38 |
39 | extern float scaledist;
40 | extern float scalecos;
41 | extern float rangescale;
42 |
43 | extern int c_culldistplane, c_proper;
44 |
45 | byte *GetFileSpace (int size);
46 | extern byte *filebase;
47 |
48 | extern vec3_t bsp_origin;
49 | extern vec3_t bsp_xvector;
50 | extern vec3_t bsp_yvector;
51 |
52 | void TransformSample (vec3_t in, vec3_t out);
53 | void RotateSample (vec3_t in, vec3_t out);
54 |
55 | extern qboolean extrasamples;
56 |
57 | extern float minlights[MAX_MAP_FACES];
58 |
--------------------------------------------------------------------------------
/qbsp/map.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 |
22 | #define MAX_FACES 16
23 | typedef struct mface_s
24 | {
25 | struct mface_s *next;
26 | plane_t plane;
27 | int texinfo;
28 | } mface_t;
29 |
30 | typedef struct mbrush_s
31 | {
32 | struct mbrush_s *next;
33 | mface_t *faces;
34 | } mbrush_t;
35 |
36 | typedef struct epair_s
37 | {
38 | struct epair_s *next;
39 | char *key;
40 | char *value;
41 | } epair_t;
42 |
43 | typedef struct
44 | {
45 | vec3_t origin;
46 | mbrush_t *brushes;
47 | epair_t *epairs;
48 | } entity_t;
49 |
50 | extern int nummapbrushes;
51 | extern mbrush_t mapbrushes[MAX_MAP_BRUSHES];
52 |
53 | extern int num_entities;
54 | extern entity_t entities[MAX_MAP_ENTITIES];
55 |
56 | extern int nummiptex;
57 | extern char miptex[MAX_MAP_TEXINFO][16];
58 |
59 | void LoadMapFile (char *filename);
60 |
61 | int FindMiptex (char *name);
62 |
63 | void PrintEntity (entity_t *ent);
64 | char *ValueForKey (entity_t *ent, char *key);
65 | void SetKeyValue (entity_t *ent, char *key, char *value);
66 | float FloatForKey (entity_t *ent, char *key);
67 | void GetVectorForKey (entity_t *ent, char *key, vec3_t vec);
68 |
69 | void WriteEntitiesToString (void);
70 |
--------------------------------------------------------------------------------
/common/wadlib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // wadlib.h
21 |
22 | //
23 | // wad reading
24 | //
25 |
26 | #define CMP_NONE 0
27 | #define CMP_LZSS 1
28 |
29 | #define TYP_NONE 0
30 | #define TYP_LABEL 1
31 | #define TYP_LUMPY 64 // 64 + grab command number
32 |
33 | typedef struct
34 | {
35 | char identification[4]; // should be WAD2 or 2DAW
36 | int numlumps;
37 | int infotableofs;
38 | } wadinfo_t;
39 |
40 |
41 | typedef struct
42 | {
43 | int filepos;
44 | int disksize;
45 | int size; // uncompressed
46 | char type;
47 | char compression;
48 | char pad1, pad2;
49 | char name[16]; // must be null terminated
50 | } lumpinfo_t;
51 |
52 | extern lumpinfo_t *lumpinfo; // location of each lump on disk
53 | extern int numlumps;
54 | extern wadinfo_t header;
55 |
56 | void W_OpenWad (char *filename);
57 | int W_CheckNumForName (char *name);
58 | int W_GetNumForName (char *name);
59 | int W_LumpLength (int lump);
60 | void W_ReadLumpNum (int lump, void *dest);
61 | void *W_LoadLumpNum (int lump);
62 | void *W_LoadLumpName (char *name);
63 |
64 | void CleanupName (char *in, char *out);
65 |
66 | //
67 | // wad creation
68 | //
69 | void NewWad (char *pathname, qboolean bigendien);
70 | void AddLump (char *name, void *buffer, int length, int type, int compress);
71 | void WriteWad (void);
72 |
73 |
--------------------------------------------------------------------------------
/common/mathlib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | #ifndef __MATHLIB__
21 | #define __MATHLIB__
22 |
23 | // mathlib.h
24 |
25 | #include
26 |
27 | #ifdef DOUBLEVEC_T
28 | typedef double vec_t;
29 | #else
30 | typedef float vec_t;
31 | #endif
32 | typedef vec_t vec3_t[3];
33 |
34 | #define SIDE_FRONT 0
35 | #define SIDE_ON 2
36 | #define SIDE_BACK 1
37 | #define SIDE_CROSS -2
38 |
39 | #define Q_PI 3.14159265358979323846
40 |
41 | extern vec3_t vec3_origin;
42 |
43 | #define EQUAL_EPSILON 0.001
44 |
45 | qboolean VectorCompare (vec3_t v1, vec3_t v2);
46 |
47 | #define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
48 | #define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
49 | #define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
50 | #define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
51 |
52 | vec_t Q_rint (vec_t in);
53 | vec_t _DotProduct (vec3_t v1, vec3_t v2);
54 | void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out);
55 | void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out);
56 | void _VectorCopy (vec3_t in, vec3_t out);
57 |
58 | double VectorLength(vec3_t v);
59 |
60 | void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc);
61 |
62 | void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
63 | vec_t VectorNormalize (vec3_t v);
64 | void VectorInverse (vec3_t v);
65 | void VectorScale (vec3_t v, vec_t scale, vec3_t out);
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/light/threads.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #include "cmdlib.h"
22 | #include "threads.h"
23 |
24 | #ifdef __alpha
25 | int numthreads = 4;
26 | pthread_mutex_t *my_mutex;
27 | #else
28 | int numthreads = 1;
29 | #endif
30 |
31 | void InitThreads (void)
32 | {
33 | #ifdef __alpha
34 | pthread_mutexattr_t mattrib;
35 |
36 | my_mutex = malloc (sizeof(*my_mutex));
37 | if (pthread_mutexattr_create (&mattrib) == -1)
38 | Error ("pthread_mutex_attr_create failed");
39 | if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
40 | Error ("pthread_mutexattr_setkind_np failed");
41 | if (pthread_mutex_init (my_mutex, mattrib) == -1)
42 | Error ("pthread_mutex_init failed");
43 | #endif
44 | }
45 |
46 | /*
47 | ===============
48 | RunThreadsOn
49 | ===============
50 | */
51 | void RunThreadsOn ( threadfunc_t func )
52 | {
53 | #ifdef __alpha
54 | pthread_t work_threads[256];
55 | pthread_addr_t status;
56 | pthread_attr_t attrib;
57 | int i;
58 |
59 | if (numthreads == 1)
60 | {
61 | func (NULL);
62 | return;
63 | }
64 |
65 | if (pthread_attr_create (&attrib) == -1)
66 | Error ("pthread_attr_create failed");
67 | if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
68 | Error ("pthread_attr_setstacksize failed");
69 |
70 | for (i=0 ; i EQUAL_EPSILON)
47 | return false;
48 |
49 | return true;
50 | }
51 |
52 | vec_t Q_rint (vec_t in)
53 | {
54 | return floor (in + 0.5);
55 | }
56 |
57 | void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc)
58 | {
59 | vc[0] = va[0] + scale*vb[0];
60 | vc[1] = va[1] + scale*vb[1];
61 | vc[2] = va[2] + scale*vb[2];
62 | }
63 |
64 | void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
65 | {
66 | cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
67 | cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
68 | cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
69 | }
70 |
71 | vec_t _DotProduct (vec3_t v1, vec3_t v2)
72 | {
73 | return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
74 | }
75 |
76 | void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out)
77 | {
78 | out[0] = va[0]-vb[0];
79 | out[1] = va[1]-vb[1];
80 | out[2] = va[2]-vb[2];
81 | }
82 |
83 | void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out)
84 | {
85 | out[0] = va[0]+vb[0];
86 | out[1] = va[1]+vb[1];
87 | out[2] = va[2]+vb[2];
88 | }
89 |
90 | void _VectorCopy (vec3_t in, vec3_t out)
91 | {
92 | out[0] = in[0];
93 | out[1] = in[1];
94 | out[2] = in[2];
95 | }
96 |
97 | vec_t VectorNormalize (vec3_t v)
98 | {
99 | int i;
100 | double length;
101 |
102 | length = 0;
103 | for (i=0 ; i< 3 ; i++)
104 | length += v[i]*v[i];
105 | length = sqrt (length);
106 | if (length == 0)
107 | return 0;
108 |
109 | for (i=0 ; i< 3 ; i++)
110 | v[i] /= length;
111 |
112 | return length;
113 | }
114 |
115 | void VectorInverse (vec3_t v)
116 | {
117 | v[0] = -v[0];
118 | v[1] = -v[1];
119 | v[2] = -v[2];
120 | }
121 |
122 | void VectorScale (vec3_t v, vec_t scale, vec3_t out)
123 | {
124 | out[0] = v[0] * scale;
125 | out[1] = v[1] * scale;
126 | out[2] = v[2] * scale;
127 | }
128 |
129 |
--------------------------------------------------------------------------------
/qc/progdefs.h:
--------------------------------------------------------------------------------
1 |
2 | /* file generated by qcc, do not modify */
3 |
4 | typedef struct
5 | { int pad[28];
6 | int self;
7 | int other;
8 | int world;
9 | float time;
10 | float frametime;
11 | int newmis;
12 | float force_retouch;
13 | string_t mapname;
14 | float serverflags;
15 | float total_secrets;
16 | float total_monsters;
17 | float found_secrets;
18 | float killed_monsters;
19 | float parm1;
20 | float parm2;
21 | float parm3;
22 | float parm4;
23 | float parm5;
24 | float parm6;
25 | float parm7;
26 | float parm8;
27 | float parm9;
28 | float parm10;
29 | float parm11;
30 | float parm12;
31 | float parm13;
32 | float parm14;
33 | float parm15;
34 | float parm16;
35 | vec3_t v_forward;
36 | vec3_t v_up;
37 | vec3_t v_right;
38 | float trace_allsolid;
39 | float trace_startsolid;
40 | float trace_fraction;
41 | vec3_t trace_endpos;
42 | vec3_t trace_plane_normal;
43 | float trace_plane_dist;
44 | int trace_ent;
45 | float trace_inopen;
46 | float trace_inwater;
47 | int msg_entity;
48 | func_t main;
49 | func_t StartFrame;
50 | func_t PlayerPreThink;
51 | func_t PlayerPostThink;
52 | func_t ClientKill;
53 | func_t ClientConnect;
54 | func_t PutClientInServer;
55 | func_t ClientDisconnect;
56 | func_t SetNewParms;
57 | func_t SetChangeParms;
58 | } globalvars_t;
59 |
60 | typedef struct
61 | {
62 | float modelindex;
63 | vec3_t absmin;
64 | vec3_t absmax;
65 | float ltime;
66 | float lastruntime;
67 | float movetype;
68 | float solid;
69 | vec3_t origin;
70 | vec3_t oldorigin;
71 | vec3_t velocity;
72 | vec3_t angles;
73 | vec3_t avelocity;
74 | string_t classname;
75 | string_t model;
76 | float frame;
77 | float skin;
78 | float effects;
79 | vec3_t mins;
80 | vec3_t maxs;
81 | vec3_t size;
82 | func_t touch;
83 | func_t use;
84 | func_t think;
85 | func_t blocked;
86 | float nextthink;
87 | int groundentity;
88 | float health;
89 | float frags;
90 | float weapon;
91 | string_t weaponmodel;
92 | float weaponframe;
93 | float currentammo;
94 | float ammo_shells;
95 | float ammo_nails;
96 | float ammo_rockets;
97 | float ammo_cells;
98 | float items;
99 | float takedamage;
100 | int chain;
101 | float deadflag;
102 | vec3_t view_ofs;
103 | float button0;
104 | float button1;
105 | float button2;
106 | float impulse;
107 | float fixangle;
108 | vec3_t v_angle;
109 | string_t netname;
110 | int enemy;
111 | float flags;
112 | float colormap;
113 | float team;
114 | float max_health;
115 | float teleport_time;
116 | float armortype;
117 | float armorvalue;
118 | float waterlevel;
119 | float watertype;
120 | float ideal_yaw;
121 | float yaw_speed;
122 | int aiment;
123 | int goalentity;
124 | float spawnflags;
125 | string_t target;
126 | string_t targetname;
127 | float dmg_take;
128 | float dmg_save;
129 | int dmg_inflictor;
130 | int owner;
131 | vec3_t movedir;
132 | string_t message;
133 | float sounds;
134 | string_t noise;
135 | string_t noise1;
136 | string_t noise2;
137 | string_t noise3;
138 | } entvars_t;
139 |
140 | #define PROGHEADER_CRC 54730
141 |
--------------------------------------------------------------------------------
/qc/spectate.qc:
--------------------------------------------------------------------------------
1 | /*
2 | spectate.qc
3 |
4 | spectator functions
5 |
6 | PURPOSE
7 |
8 | Copyright (C) 1996-1997 Id Software, Inc.
9 |
10 | This program is free software; you can redistribute it and/or
11 | modify it under the terms of the GNU General Public License
12 | as published by the Free Software Foundation; either version 2
13 | of the License, or (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 |
19 | See the GNU General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with this program; if not, write to:
23 |
24 | Free Software Foundation, Inc.
25 | 59 Temple Place - Suite 330
26 | Boston, MA 02111-1307, USA
27 |
28 | */
29 | // Added Aug11'97 by Zoid
30 | //
31 | // These functions are called from the server if they exist.
32 | // Note that Spectators only have one think since they movement code doesn't
33 | // track them much. Impulse commands work as usual, but don't call
34 | // the regular ImpulseCommand handler in weapons.qc since Spectators don't
35 | // have any weapons and things can explode.
36 | //
37 | // --- Zoid.
38 |
39 | /*
40 | ===========
41 | SpectatorConnect
42 |
43 | called when a spectator connects to a server
44 | ============
45 | */
46 | void() SpectatorConnect =
47 | {
48 | bprint (PRINT_MEDIUM, "Spectator ");
49 | bprint (PRINT_MEDIUM, self.netname);
50 | bprint (PRINT_MEDIUM, " entered the game\n");
51 |
52 | self.goalentity = world; // used for impulse 1 below
53 | };
54 |
55 | /*
56 | ===========
57 | SpectatorDisconnect
58 |
59 | called when a spectator disconnects from a server
60 | ============
61 | */
62 | void() SpectatorDisconnect =
63 | {
64 | bprint (PRINT_MEDIUM, "Spectator ");
65 | bprint (PRINT_MEDIUM, self.netname);
66 | bprint (PRINT_MEDIUM, " left the game\n");
67 | };
68 |
69 | /*
70 | ================
71 | SpectatorImpulseCommand
72 |
73 | Called by SpectatorThink if the spectator entered an impulse
74 | ================
75 | */
76 | void() SpectatorImpulseCommand =
77 | {
78 | if (self.impulse == 1) {
79 | // teleport the spectator to the next spawn point
80 | // note that if the spectator is tracking, this doesn't do
81 | // much
82 | self.goalentity = find(self.goalentity, classname, "info_player_deathmatch");
83 | if (self.goalentity == world)
84 | self.goalentity = find(self.goalentity, classname, "info_player_deathmatch");
85 | if (self.goalentity != world) {
86 | setorigin(self, self.goalentity.origin);
87 | self.angles = self.goalentity.angles;
88 | self.fixangle = TRUE; // turn this way immediately
89 | }
90 | }
91 |
92 | self.impulse = 0;
93 | };
94 |
95 | /*
96 | ================
97 | SpectatorThink
98 |
99 | Called every frame after physics are run
100 | ================
101 | */
102 | void() SpectatorThink =
103 | {
104 | // self.origin, etc contains spectator position, so you could
105 | // do some neat stuff here
106 |
107 | if (self.impulse)
108 | SpectatorImpulseCommand();
109 | };
110 |
111 |
112 |
--------------------------------------------------------------------------------
/qbsp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qbsp", "qbsp\qbsp.vcxproj", "{21D59AF6-0F02-40E5-B4F7-4CF27D6A8C4F}"
5 | ProjectSection(ProjectDependencies) = postProject
6 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD} = {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}
7 | EndProjectSection
8 | EndProject
9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxproj", "{743626C6-FD32-4C6D-BA62-F8BEA39F51FD}"
10 | EndProject
11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vis", "vis\vis.vcxproj", "{DD804337-3C39-41C0-B84A-1FF25CF44ADA}"
12 | EndProject
13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "light", "light\light.vcxproj", "{769A8669-6F8E-4DDE-B5EA-354FCB02415E}"
14 | ProjectSection(ProjectDependencies) = postProject
15 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD} = {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}
16 | EndProjectSection
17 | EndProject
18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qcc", "qcc\qcc.vcxproj", "{F235A057-0EB0-4AA3-AD00-CB1499C88AF2}"
19 | ProjectSection(ProjectDependencies) = postProject
20 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD} = {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}
21 | EndProjectSection
22 | EndProject
23 | Global
24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 | Debug|Win32 = Debug|Win32
26 | Release|Win32 = Release|Win32
27 | EndGlobalSection
28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
29 | {21D59AF6-0F02-40E5-B4F7-4CF27D6A8C4F}.Debug|Win32.ActiveCfg = Debug|Win32
30 | {21D59AF6-0F02-40E5-B4F7-4CF27D6A8C4F}.Debug|Win32.Build.0 = Debug|Win32
31 | {21D59AF6-0F02-40E5-B4F7-4CF27D6A8C4F}.Release|Win32.ActiveCfg = Release|Win32
32 | {21D59AF6-0F02-40E5-B4F7-4CF27D6A8C4F}.Release|Win32.Build.0 = Release|Win32
33 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}.Debug|Win32.ActiveCfg = Debug|Win32
34 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}.Debug|Win32.Build.0 = Debug|Win32
35 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}.Release|Win32.ActiveCfg = Release|Win32
36 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}.Release|Win32.Build.0 = Release|Win32
37 | {DD804337-3C39-41C0-B84A-1FF25CF44ADA}.Debug|Win32.ActiveCfg = Debug|Win32
38 | {DD804337-3C39-41C0-B84A-1FF25CF44ADA}.Debug|Win32.Build.0 = Debug|Win32
39 | {DD804337-3C39-41C0-B84A-1FF25CF44ADA}.Release|Win32.ActiveCfg = Release|Win32
40 | {DD804337-3C39-41C0-B84A-1FF25CF44ADA}.Release|Win32.Build.0 = Release|Win32
41 | {769A8669-6F8E-4DDE-B5EA-354FCB02415E}.Debug|Win32.ActiveCfg = Debug|Win32
42 | {769A8669-6F8E-4DDE-B5EA-354FCB02415E}.Debug|Win32.Build.0 = Debug|Win32
43 | {769A8669-6F8E-4DDE-B5EA-354FCB02415E}.Release|Win32.ActiveCfg = Release|Win32
44 | {769A8669-6F8E-4DDE-B5EA-354FCB02415E}.Release|Win32.Build.0 = Release|Win32
45 | {F235A057-0EB0-4AA3-AD00-CB1499C88AF2}.Debug|Win32.ActiveCfg = Debug|Win32
46 | {F235A057-0EB0-4AA3-AD00-CB1499C88AF2}.Debug|Win32.Build.0 = Debug|Win32
47 | {F235A057-0EB0-4AA3-AD00-CB1499C88AF2}.Release|Win32.ActiveCfg = Release|Win32
48 | {F235A057-0EB0-4AA3-AD00-CB1499C88AF2}.Release|Win32.Build.0 = Release|Win32
49 | EndGlobalSection
50 | GlobalSection(SolutionProperties) = preSolution
51 | HideSolutionNode = FALSE
52 | EndGlobalSection
53 | EndGlobal
54 |
--------------------------------------------------------------------------------
/xcode/qcc/qcc.xcodeproj/xcuserdata/fabiensanglard.xcuserdatad/xcschemes/qcc.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
14 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
49 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
67 |
68 |
74 |
75 |
76 |
77 |
79 |
80 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/xcode/light/light.xcodeproj/xcuserdata/fabiensanglard.xcuserdatad/xcschemes/light.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
14 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
49 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
67 |
68 |
74 |
75 |
76 |
77 |
79 |
80 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/common/cmdlib.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // cmdlib.h
21 |
22 | #ifndef __CMDLIB__
23 | #define __CMDLIB__
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | #ifndef __BYTEBOOL__
34 | #define __BYTEBOOL__
35 | typedef enum {false, true} qboolean;
36 | typedef unsigned char byte;
37 | #endif
38 |
39 | // the dec offsetof macro doesn't work very well...
40 | #define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
41 |
42 |
43 | // set these before calling CheckParm
44 | extern int myargc;
45 | extern char **myargv;
46 |
47 | char *strupr (char *in);
48 | char *strlower (char *in);
49 | int Q_strncasecmp (char *s1, char *s2, int n);
50 | int Q_strcasecmp (char *s1, char *s2);
51 | void Q_getwd (char *out);
52 |
53 | int filelength (FILE *f);
54 | int FileTime (char *path);
55 |
56 | void Q_mkdir (char *path);
57 |
58 | extern char qdir[1024];
59 | extern char gamedir[1024];
60 | void SetQdirFromPath (char *path);
61 | char *ExpandPath (char *path);
62 | char *ExpandPathAndArchive (char *path);
63 |
64 |
65 | double I_FloatTime (void);
66 |
67 | void Error (char *error, ...);
68 | int CheckParm (char *check);
69 |
70 | FILE *SafeOpenWrite (char *filename);
71 | FILE *SafeOpenRead (char *filename);
72 | void SafeRead (FILE *f, void *buffer, int count);
73 | void SafeWrite (FILE *f, void *buffer, int count);
74 |
75 | int LoadFile (char *filename, void **bufferptr);
76 | void SaveFile (char *filename, void *buffer, int count);
77 |
78 | void DefaultExtension (char *path, char *extension);
79 | void DefaultPath (char *path, char *basepath);
80 | void StripFilename (char *path);
81 | void StripExtension (char *path);
82 |
83 | void ExtractFilePath (char *path, char *dest);
84 | void ExtractFileBase (char *path, char *dest);
85 | void ExtractFileExtension (char *path, char *dest);
86 |
87 | int ParseNum (char *str);
88 |
89 | short BigShort (short l);
90 | short LittleShort (short l);
91 | int BigLong (int l);
92 | int LittleLong (int l);
93 | float BigFloat (float l);
94 | float LittleFloat (float l);
95 |
96 |
97 | char *COM_Parse (char *data);
98 |
99 | extern char com_token[1024];
100 | extern qboolean com_eof;
101 |
102 | char *copystring(char *s);
103 |
104 |
105 | void CRC_Init(unsigned short *crcvalue);
106 | void CRC_ProcessByte(unsigned short *crcvalue, byte data);
107 | unsigned short CRC_Value(unsigned short crcvalue);
108 |
109 | void CreatePath (char *path);
110 | void CopyFile (char *from, char *to);
111 |
112 | extern qboolean archive;
113 | extern char archivedir[1024];
114 |
115 |
116 | #endif
117 |
--------------------------------------------------------------------------------
/light/light.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // lighting.c
21 |
22 | #include "light.h"
23 |
24 | /*
25 |
26 | NOTES
27 | -----
28 |
29 | */
30 |
31 | float scaledist = 1.0;
32 | float scalecos = 0.5;
33 | float rangescale = 0.5;
34 |
35 | byte *filebase, *file_p, *file_end;
36 |
37 | dmodel_t *bspmodel;
38 | int bspfileface; // next surface to dispatch
39 |
40 | vec3_t bsp_origin;
41 |
42 | qboolean extrasamples;
43 |
44 | float minlights[MAX_MAP_FACES];
45 |
46 |
47 | byte *GetFileSpace (int size)
48 | {
49 | byte *buf;
50 |
51 | LOCK;
52 | file_p = (byte *)(((long)file_p + 3)&~3);
53 | buf = file_p;
54 | file_p += size;
55 | UNLOCK;
56 | if (file_p > file_end)
57 | Error ("GetFileSpace: overrun");
58 | return buf;
59 | }
60 |
61 |
62 | void LightThread (void *junk)
63 | {
64 | int i;
65 |
66 | while (1)
67 | {
68 | LOCK;
69 | i = bspfileface++;
70 | UNLOCK;
71 | if (i >= numfaces)
72 | return;
73 |
74 | LightFace (i);
75 | }
76 | }
77 |
78 | /*
79 | =============
80 | LightWorld
81 | =============
82 | */
83 | void LightWorld (void)
84 | {
85 | filebase = file_p = dlightdata;
86 | file_end = filebase + MAX_MAP_LIGHTING;
87 |
88 | RunThreadsOn (LightThread);
89 |
90 | lightdatasize = file_p - filebase;
91 |
92 | printf ("lightdatasize: %i\n", lightdatasize);
93 | }
94 |
95 |
96 | /*
97 | ========
98 | main
99 |
100 | light modelfile
101 | ========
102 | */
103 | int main (int argc, char **argv)
104 | {
105 | int i;
106 | double start, end;
107 | char source[1024];
108 |
109 | printf ("----- LightFaces ----\n");
110 |
111 | for (i=1 ; i East wall:p[1]
11 | {
12 | ( 432 0 96 ) ( 432 128 96 ) ( 560 0 96 ) bricka2_2 -432 0 0 1 1 //TX1
13 | ( 432 0 -96 ) ( 432 -128 -96 ) ( 560 0 -96 ) bricka2_2 -432 0 0 1 -1 //TX1
14 | ( 432 192 272 ) ( 432 192 400 ) ( 304 192 272 ) bricka2_2 432 272 0 -1 1 //TX1
15 | ( 432 -192 272 ) ( 432 -192 400 ) ( 560 -192 272 ) bricka2_2 -432 272 0 1 1 //TX1
16 | ( 272 0 272 ) ( 272 0 400 ) ( 272 128 272 ) bricka2_2 0 272 0 1 1 //TX1
17 | ( 256 0 272 ) ( 256 0 400 ) ( 256 -128 272 ) bricka2_2 0 272 0 -1 1 //TX1
18 | }
19 | // Brush 1
20 | // Border walls:g[1] -> West wall:p[2]
21 | {
22 | ( 432 0 96 ) ( 432 128 96 ) ( 560 0 96 ) bricka2_2 -432 0 0 1 1 //TX1
23 | ( 432 0 -96 ) ( 432 -128 -96 ) ( 560 0 -96 ) bricka2_2 -432 0 0 1 -1 //TX1
24 | ( 432 192 272 ) ( 432 192 400 ) ( 304 192 272 ) bricka2_2 432 272 0 -1 1 //TX1
25 | ( 432 -192 272 ) ( 432 -192 400 ) ( 560 -192 272 ) bricka2_2 -432 272 0 1 1 //TX1
26 | ( -256 0 272 ) ( -256 0 400 ) ( -256 128 272 ) bricka2_2 0 272 0 1 1 //TX1
27 | ( -272 0 272 ) ( -272 0 400 ) ( -272 -128 272 ) bricka2_2 0 272 0 -1 1 //TX1
28 | }
29 | // Brush 2
30 | // Border walls:g[1] -> North wall:p[3]
31 | {
32 | ( 432 0 96 ) ( 432 128 96 ) ( 560 0 96 ) bricka2_2 -432 0 0 1 1 //TX1
33 | ( 432 0 -96 ) ( 432 -128 -96 ) ( 560 0 -96 ) bricka2_2 -432 0 0 1 -1 //TX1
34 | ( 432 208 272 ) ( 432 208 400 ) ( 304 208 272 ) bricka2_2 432 272 0 -1 1 //TX1
35 | ( 432 192 272 ) ( 432 192 400 ) ( 560 192 272 ) bricka2_2 -432 272 0 1 1 //TX1
36 | ( 256 0 272 ) ( 256 0 400 ) ( 256 128 272 ) bricka2_2 0 272 0 1 1 //TX1
37 | ( -256 0 272 ) ( -256 0 400 ) ( -256 -128 272 ) bricka2_2 0 272 0 -1 1 //TX1
38 | }
39 | // Brush 3
40 | // Border walls:g[1] -> South wall:p[4]
41 | {
42 | ( 432 0 96 ) ( 432 128 96 ) ( 560 0 96 ) bricka2_2 -432 0 0 1 1 //TX1
43 | ( 432 0 -96 ) ( 432 -128 -96 ) ( 560 0 -96 ) bricka2_2 -432 0 0 1 -1 //TX1
44 | ( 432 -192 272 ) ( 432 -192 400 ) ( 304 -192 272 ) bricka2_2 432 272 0 -1 1 //TX1
45 | ( 432 -208 272 ) ( 432 -208 400 ) ( 560 -208 272 ) bricka2_2 -432 272 0 1 1 //TX1
46 | ( 256 0 272 ) ( 256 0 400 ) ( 256 128 272 ) bricka2_2 0 272 0 1 1 //TX1
47 | ( -256 0 272 ) ( -256 0 400 ) ( -256 -128 272 ) bricka2_2 0 272 0 -1 1 //TX1
48 | }
49 | // Brush 4
50 | // Border walls:g[1] -> Sky:p[5]
51 | {
52 | ( 432 0 112 ) ( 432 128 112 ) ( 560 0 112 ) sky1 -432 0 0 1 1 //TX1
53 | ( 432 0 96 ) ( 432 -128 96 ) ( 560 0 96 ) sky1 -432 0 0 1 -1 //TX1
54 | ( 432 192 272 ) ( 432 192 400 ) ( 304 192 272 ) sky1 432 272 0 -1 1 //TX1
55 | ( 432 -192 272 ) ( 432 -192 400 ) ( 560 -192 272 ) sky1 -432 272 0 1 1 //TX1
56 | ( 256 0 272 ) ( 256 0 400 ) ( 256 128 272 ) sky1 0 272 0 1 1 //TX1
57 | ( -256 0 272 ) ( -256 0 400 ) ( -256 -128 272 ) sky1 0 272 0 -1 1 //TX1
58 | }
59 | // Brush 5
60 | // Border walls:g[1] -> Floor:p[6]
61 | {
62 | ( 432 0 -96 ) ( 432 128 -96 ) ( 560 0 -96 ) woodflr1_5 -432 0 0 1 1 //TX1
63 | ( 432 0 -112 ) ( 432 -128 -112 ) ( 560 0 -112 ) woodflr1_5 -432 0 0 1 -1 //TX1
64 | ( 432 192 272 ) ( 432 192 400 ) ( 304 192 272 ) woodflr1_5 432 272 0 -1 1 //TX1
65 | ( 432 -192 272 ) ( 432 -192 400 ) ( 560 -192 272 ) woodflr1_5 -432 272 0 1 1 //TX1
66 | ( 256 0 272 ) ( 256 0 400 ) ( 256 128 272 ) woodflr1_5 0 272 0 1 1 //TX1
67 | ( -256 0 272 ) ( -256 0 400 ) ( -256 -128 272 ) woodflr1_5 0 272 0 -1 1 //TX1
68 | }
69 | }
70 | // Entity 1
71 | // info_player_start:e[2]
72 | {
73 | "classname" "info_player_start"
74 | "origin" "-144 0 -72"
75 | "angle" "360"
76 | }
77 | // Entity 2
78 | // light:e[3]
79 | {
80 | "classname" "light"
81 | "light" "300"
82 | "angle" "360"
83 | "origin" "0 0 0"
84 | }
85 |
--------------------------------------------------------------------------------
/vis/vis.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // vis.h
21 |
22 | #include "cmdlib.h"
23 | #include "mathlib.h"
24 | #include "bspfile.h"
25 |
26 | #define MAX_PORTALS 32768
27 |
28 | #define PORTALFILE "PRT1"
29 |
30 | #define ON_EPSILON 0.1
31 |
32 | typedef struct
33 | {
34 | vec3_t normal;
35 | float dist;
36 | } plane_t;
37 |
38 | typedef struct
39 | {
40 | qboolean original; // don't free, it's part of the portal
41 | int numpoints;
42 | vec3_t points[8]; // variable sized
43 | } winding_t;
44 |
45 | #define MAX_POINTS_ON_WINDING 64
46 |
47 | winding_t *NewWinding (int points);
48 | void FreeWinding (winding_t *w);
49 | winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon);
50 | winding_t *CopyWinding (winding_t *w);
51 |
52 |
53 | typedef enum {stat_none, stat_working, stat_done} vstatus_t;
54 | typedef struct
55 | {
56 | plane_t plane; // normal pointing into neighbor
57 | int leaf; // neighbor //FCS: WTF is this and where is it set ?
58 | winding_t *winding;
59 | vstatus_t status;
60 | byte *visbits;
61 | byte *mightsee;
62 | int nummightsee;
63 | int numcansee;
64 | } portal_t;
65 |
66 | typedef struct seperating_plane_s
67 | {
68 | struct seperating_plane_s *next;
69 | plane_t plane; // from portal is on positive side
70 | } sep_t;
71 |
72 |
73 | typedef struct passage_s
74 | {
75 | struct passage_s *next;
76 | int from, to; // leaf numbers
77 | sep_t *planes;
78 | } passage_t;
79 |
80 | #define MAX_PORTALS_ON_LEAF 128
81 | typedef struct leaf_s
82 | {
83 | int numportals;
84 | passage_t *passages;
85 | portal_t *portals[MAX_PORTALS_ON_LEAF];
86 | } leaf_t;
87 |
88 |
89 | typedef struct pstack_s
90 | {
91 | struct pstack_s *next;
92 | leaf_t *leaf;
93 | portal_t *portal; // portal exiting
94 | winding_t *source, *pass;
95 | plane_t portalplane;
96 | byte *mightsee; // bit string
97 | } pstack_t;
98 |
99 | typedef struct
100 | {
101 | byte *leafvis; // bit string
102 | portal_t *base;
103 | pstack_t pstack_head;
104 | } threaddata_t;
105 |
106 | //FCS __unix__ also include macosx
107 | #if defined(__alpha) || defined(__APPLE__)
108 | #include
109 | extern pthread_mutex_t *my_mutex;
110 | #define LOCK pthread_mutex_lock (my_mutex)
111 | #define UNLOCK pthread_mutex_unlock (my_mutex)
112 | #else
113 | #define LOCK
114 | #define UNLOCK
115 | #endif
116 |
117 |
118 | extern int numportals;
119 | extern int portalleafs;
120 |
121 | extern portal_t *portals;
122 | extern leaf_t *leafs;
123 |
124 | extern int c_portaltest, c_portalpass, c_portalcheck;
125 | extern int c_portalskip, c_leafskip;
126 | extern int c_vistest, c_mighttest;
127 | extern int c_chains;
128 |
129 | extern byte *vismap, *vismap_p, *vismap_end; // past visfile
130 |
131 | extern qboolean showgetleaf;
132 | extern int testlevel;
133 |
134 | extern byte *uncompressed;
135 | extern int bitbytes;
136 | extern int bitlongs;
137 |
138 |
139 | void LeafFlow (int leafnum);
140 | void BasePortalVis (void);
141 |
142 | void PortalFlow (portal_t *p);
143 |
144 | void CalcAmbientSounds (void);
145 |
--------------------------------------------------------------------------------
/qcc/pr_comp.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | // this file is shared by quake and qcc
22 |
23 | typedef int func_t;
24 | typedef int string_t;
25 |
26 | typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer} etype_t;
27 |
28 |
29 | #define OFS_NULL 0
30 | #define OFS_RETURN 1
31 | #define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors
32 | #define OFS_PARM1 7
33 | #define OFS_PARM2 10
34 | #define OFS_PARM3 13
35 | #define OFS_PARM4 16
36 | #define OFS_PARM5 19
37 | #define OFS_PARM6 22
38 | #define OFS_PARM7 25
39 | #define RESERVED_OFS 28
40 |
41 |
42 | enum {
43 | OP_DONE,
44 | OP_MUL_F,
45 | OP_MUL_V,
46 | OP_MUL_FV,
47 | OP_MUL_VF,
48 | OP_DIV_F,
49 | OP_ADD_F,
50 | OP_ADD_V,
51 | OP_SUB_F,
52 | OP_SUB_V,
53 |
54 | OP_EQ_F,
55 | OP_EQ_V,
56 | OP_EQ_S,
57 | OP_EQ_E,
58 | OP_EQ_FNC,
59 |
60 | OP_NE_F,
61 | OP_NE_V,
62 | OP_NE_S,
63 | OP_NE_E,
64 | OP_NE_FNC,
65 |
66 | OP_LE,
67 | OP_GE,
68 | OP_LT,
69 | OP_GT,
70 |
71 | OP_LOAD_F,
72 | OP_LOAD_V,
73 | OP_LOAD_S,
74 | OP_LOAD_ENT,
75 | OP_LOAD_FLD,
76 | OP_LOAD_FNC,
77 |
78 | OP_ADDRESS,
79 |
80 | OP_STORE_F,
81 | OP_STORE_V,
82 | OP_STORE_S,
83 | OP_STORE_ENT,
84 | OP_STORE_FLD,
85 | OP_STORE_FNC,
86 |
87 | OP_STOREP_F,
88 | OP_STOREP_V,
89 | OP_STOREP_S,
90 | OP_STOREP_ENT,
91 | OP_STOREP_FLD,
92 | OP_STOREP_FNC,
93 |
94 | OP_RETURN,
95 | OP_NOT_F,
96 | OP_NOT_V,
97 | OP_NOT_S,
98 | OP_NOT_ENT,
99 | OP_NOT_FNC,
100 | OP_IF,
101 | OP_IFNOT,
102 | OP_CALL0,
103 | OP_CALL1,
104 | OP_CALL2,
105 | OP_CALL3,
106 | OP_CALL4,
107 | OP_CALL5,
108 | OP_CALL6,
109 | OP_CALL7,
110 | OP_CALL8,
111 | OP_STATE,
112 | OP_GOTO,
113 | OP_AND,
114 | OP_OR,
115 |
116 | OP_BITAND,
117 | OP_BITOR
118 | };
119 |
120 |
121 | typedef struct statement_s
122 | {
123 | unsigned short op;
124 | short a,b,c;
125 | } dstatement_t;
126 |
127 | typedef struct
128 | {
129 | unsigned short type; // if DEF_SAVEGLOBGAL bit is set
130 | // the variable needs to be saved in savegames
131 | unsigned short ofs;
132 | int s_name;
133 | } ddef_t;
134 | #define DEF_SAVEGLOBGAL (1<<15)
135 |
136 | #define MAX_PARMS 8
137 |
138 | typedef struct
139 | {
140 | int first_statement; // negative numbers are builtins
141 | int parm_start;
142 | int locals; // total ints of parms + locals
143 |
144 | int profile; // runtime
145 |
146 | int s_name;
147 | int s_file; // source file defined in
148 |
149 | int numparms;
150 | byte parm_size[MAX_PARMS];
151 | } dfunction_t;
152 |
153 |
154 | #define PROG_VERSION 6
155 | typedef struct
156 | {
157 | int version;
158 | int crc; // check of header file
159 |
160 | int ofs_statements;
161 | int numstatements; // statement 0 is an error
162 |
163 | int ofs_globaldefs;
164 | int numglobaldefs;
165 |
166 | int ofs_fielddefs;
167 | int numfielddefs;
168 |
169 | int ofs_functions;
170 | int numfunctions; // function 0 is an empty
171 |
172 | int ofs_strings;
173 | int numstrings; // first string is a null string
174 |
175 | int ofs_globals;
176 | int numglobals;
177 |
178 | int entityfields;
179 | } dprograms_t;
180 |
181 |
--------------------------------------------------------------------------------
/vis/soundpvs.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #include "vis.h"
22 |
23 | /*
24 |
25 | Some textures (sky, water, slime, lava) are considered ambien sound emiters.
26 | Find an aproximate distance to the nearest emiter of each class for each leaf.
27 |
28 | */
29 |
30 |
31 | /*
32 | ====================
33 | SurfaceBBox
34 |
35 | ====================
36 | */
37 | void SurfaceBBox (dface_t *s, vec3_t mins, vec3_t maxs)
38 | {
39 | int i, j;
40 | int e;
41 | int vi;
42 | float *v;
43 |
44 | mins[0] = mins[1] = 999999;
45 | maxs[0] = maxs[1] = -99999;
46 |
47 | for (i=0 ; inumedges ; i++)
48 | {
49 | e = dsurfedges[s->firstedge+i];
50 | if (e >= 0)
51 | vi = dedges[e].v[0];
52 | else
53 | vi = dedges[-e].v[1];
54 | v = dvertexes[vi].point;
55 |
56 | for (j=0 ; j<3 ; j++)
57 | {
58 | if (v[j] < mins[j])
59 | mins[j] = v[j];
60 | if (v[j] > maxs[j])
61 | maxs[j] = v[j];
62 | }
63 | }
64 | }
65 |
66 |
67 | /*
68 | ====================
69 | CalcAmbientSounds
70 |
71 | ====================
72 | */
73 | void CalcAmbientSounds (void)
74 | {
75 | int i, j, k, l;
76 | dleaf_t *leaf, *hit;
77 | byte *vis;
78 | dface_t *surf;
79 | vec3_t mins, maxs;
80 | float d, maxd;
81 | int ambient_type;
82 | texinfo_t *info;
83 | miptex_t *miptex;
84 | int ofs;
85 | float dists[NUM_AMBIENTS];
86 | float vol;
87 |
88 | for (i=0 ; i< portalleafs ; i++)
89 | {
90 | leaf = &dleafs[i+1];
91 |
92 | //
93 | // clear ambients
94 | //
95 | for (j=0 ; j>3] & (1<<(j&7))) )
103 | continue;
104 |
105 | //
106 | // check this leaf for sound textures
107 | //
108 | hit = &dleafs[j+1];
109 |
110 | for (k=0 ; k< hit->nummarksurfaces ; k++)
111 | {
112 | surf = &dfaces[dmarksurfaces[hit->firstmarksurface + k]];
113 | info = &texinfo[surf->texinfo];
114 | ofs = ((dmiptexlump_t *)dtexdata)->dataofs[info->miptex];
115 | miptex = (miptex_t *)(&dtexdata[ofs]);
116 |
117 | if ( !Q_strncasecmp (miptex->name, "*water", 6) )
118 | ambient_type = AMBIENT_WATER;
119 | else if ( !Q_strncasecmp (miptex->name, "sky", 3) )
120 | ambient_type = AMBIENT_SKY;
121 | else if ( !Q_strncasecmp (miptex->name, "*slime", 6) )
122 | ambient_type = AMBIENT_WATER; // AMBIENT_SLIME;
123 | else if ( !Q_strncasecmp (miptex->name, "*lava", 6) )
124 | ambient_type = AMBIENT_LAVA;
125 | else if ( !Q_strncasecmp (miptex->name, "*04water", 8) )
126 | ambient_type = AMBIENT_WATER;
127 | else
128 | continue;
129 |
130 | // find distance from source leaf to polygon
131 | SurfaceBBox (surf, mins, maxs);
132 | maxd = 0;
133 | for (l=0 ; l<3 ; l++)
134 | {
135 | if (mins[l] > leaf->maxs[l])
136 | d = mins[l] - leaf->maxs[l];
137 | else if (maxs[l] < leaf->mins[l])
138 | d = leaf->mins[l] - mins[l];
139 | else
140 | d = 0;
141 | if (d > maxd)
142 | maxd = d;
143 | }
144 |
145 | maxd = 0.25;
146 | if (maxd < dists[ambient_type])
147 | dists[ambient_type] = maxd;
148 | }
149 | }
150 |
151 | for (j=0 ; jambient_level[j] = vol*255;
162 | }
163 | }
164 | }
165 |
166 |
--------------------------------------------------------------------------------
/qc/buttons.qc:
--------------------------------------------------------------------------------
1 | /*
2 | buttons.qc
3 |
4 | button and multiple button
5 |
6 | Copyright (C) 1996-1997 Id Software, Inc.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 |
17 | See the GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to:
21 |
22 | Free Software Foundation, Inc.
23 | 59 Temple Place - Suite 330
24 | Boston, MA 02111-1307, USA
25 |
26 | */
27 |
28 | void() button_wait;
29 | void() button_return;
30 |
31 | void() button_wait =
32 | {
33 | self.state = STATE_TOP;
34 | self.nextthink = self.ltime + self.wait;
35 | self.think = button_return;
36 | activator = self.enemy;
37 | SUB_UseTargets();
38 | self.frame = 1; // use alternate textures
39 | };
40 |
41 | void() button_done =
42 | {
43 | self.state = STATE_BOTTOM;
44 | };
45 |
46 | void() button_return =
47 | {
48 | self.state = STATE_DOWN;
49 | SUB_CalcMove (self.pos1, self.speed, button_done);
50 | self.frame = 0; // use normal textures
51 | if (self.health)
52 | self.takedamage = DAMAGE_YES; // can be shot again
53 | };
54 |
55 |
56 | void() button_blocked =
57 | { // do nothing, just don't ome all the way back out
58 | };
59 |
60 |
61 | void() button_fire =
62 | {
63 | if (self.state == STATE_UP || self.state == STATE_TOP)
64 | return;
65 |
66 | sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
67 |
68 | self.state = STATE_UP;
69 | SUB_CalcMove (self.pos2, self.speed, button_wait);
70 | };
71 |
72 |
73 | void() button_use =
74 | {
75 | self.enemy = activator;
76 | button_fire ();
77 | };
78 |
79 | void() button_touch =
80 | {
81 | if (other.classname != "player")
82 | return;
83 | self.enemy = other;
84 | button_fire ();
85 | };
86 |
87 | void() button_killed =
88 | {
89 | self.enemy = damage_attacker;
90 | self.health = self.max_health;
91 | self.takedamage = DAMAGE_NO; // wil be reset upon return
92 | button_fire ();
93 | };
94 |
95 |
96 | /*QUAKED func_button (0 .5 .8) ?
97 | When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
98 |
99 | "angle" determines the opening direction
100 | "target" all entities with a matching targetname will be used
101 | "speed" override the default 40 speed
102 | "wait" override the default 1 second wait (-1 = never return)
103 | "lip" override the default 4 pixel lip remaining at end of move
104 | "health" if set, the button must be killed instead of touched
105 | "sounds"
106 | 0) steam metal
107 | 1) wooden clunk
108 | 2) metallic click
109 | 3) in-out
110 | */
111 | void() func_button =
112 | {
113 | local float gtemp, ftemp;
114 |
115 | if (self.sounds == 0)
116 | {
117 | precache_sound ("buttons/airbut1.wav");
118 | self.noise = "buttons/airbut1.wav";
119 | }
120 | if (self.sounds == 1)
121 | {
122 | precache_sound ("buttons/switch21.wav");
123 | self.noise = "buttons/switch21.wav";
124 | }
125 | if (self.sounds == 2)
126 | {
127 | precache_sound ("buttons/switch02.wav");
128 | self.noise = "buttons/switch02.wav";
129 | }
130 | if (self.sounds == 3)
131 | {
132 | precache_sound ("buttons/switch04.wav");
133 | self.noise = "buttons/switch04.wav";
134 | }
135 |
136 | SetMovedir ();
137 |
138 | self.movetype = MOVETYPE_PUSH;
139 | self.solid = SOLID_BSP;
140 | setmodel (self, self.model);
141 |
142 | self.blocked = button_blocked;
143 | self.use = button_use;
144 |
145 | if (self.health)
146 | {
147 | self.max_health = self.health;
148 | self.th_die = button_killed;
149 | self.takedamage = DAMAGE_YES;
150 | }
151 | else
152 | self.touch = button_touch;
153 |
154 | if (!self.speed)
155 | self.speed = 40;
156 | if (!self.wait)
157 | self.wait = 1;
158 | if (!self.lip)
159 | self.lip = 4;
160 |
161 | self.state = STATE_BOTTOM;
162 |
163 | self.pos1 = self.origin;
164 | self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
165 | };
166 |
167 |
--------------------------------------------------------------------------------
/common/scriplib.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // scriplib.c
21 |
22 | #include "cmdlib.h"
23 | #include "scriplib.h"
24 |
25 | /*
26 | =============================================================================
27 |
28 | PARSING STUFF
29 |
30 | =============================================================================
31 | */
32 |
33 | char token[MAXTOKEN];
34 | char *scriptbuffer,*script_p,*scriptend_p;
35 | int grabbed;
36 | int scriptline;
37 | qboolean endofscript;
38 | qboolean tokenready; // only true if UnGetToken was just called
39 |
40 | /*
41 | ==============
42 | =
43 | = LoadScriptFile
44 | =
45 | ==============
46 | */
47 |
48 | void LoadScriptFile (char *filename)
49 | {
50 | int size;
51 |
52 | size = LoadFile (filename, (void **)&scriptbuffer);
53 |
54 | script_p = scriptbuffer;
55 | scriptend_p = script_p + size;
56 | scriptline = 1;
57 | endofscript = false;
58 | tokenready = false;
59 | }
60 |
61 |
62 | /*
63 | ==============
64 | =
65 | = UnGetToken
66 | =
67 | = Signals that the current token was not used, and should be reported
68 | = for the next GetToken. Note that
69 |
70 | GetToken (true);
71 | UnGetToken ();
72 | GetToken (false);
73 |
74 | = could cross a line boundary.
75 | =
76 | ==============
77 | */
78 |
79 | void UnGetToken (void)
80 | {
81 | tokenready = true;
82 | }
83 |
84 |
85 | /*
86 | ==============
87 | GetToken
88 | ==============
89 | */
90 | qboolean GetToken (qboolean crossline)
91 | {
92 | char *token_p;
93 |
94 | if (tokenready) // is a token allready waiting?
95 | {
96 | tokenready = false;
97 | return true;
98 | }
99 |
100 | if (script_p >= scriptend_p)
101 | {
102 | if (!crossline)
103 | Error ("Line %i is incomplete\n",scriptline);
104 | endofscript = true;
105 | return false;
106 | }
107 |
108 | //
109 | // skip space
110 | //
111 | skipspace:
112 | while (*script_p <= 32)
113 | {
114 | if (script_p >= scriptend_p)
115 | {
116 | if (!crossline)
117 | Error ("Line %i is incomplete\n",scriptline);
118 | endofscript = true;
119 | return true;
120 | }
121 | if (*script_p++ == '\n')
122 | {
123 | if (!crossline)
124 | Error ("Line %i is incomplete\n",scriptline);
125 | scriptline++;
126 | }
127 | }
128 |
129 | if (script_p >= scriptend_p)
130 | {
131 | if (!crossline)
132 | Error ("Line %i is incomplete\n",scriptline);
133 | endofscript = true;
134 | return true;
135 | }
136 |
137 | if (*script_p == ';' || *script_p == '#') // semicolon is comment field
138 | { // also make # a comment field
139 | if (!crossline)
140 | Error ("Line %i is incomplete\n",scriptline);
141 | while (*script_p++ != '\n')
142 | if (script_p >= scriptend_p)
143 | {
144 | endofscript = true;
145 | return false;
146 | }
147 | goto skipspace;
148 | }
149 |
150 | //
151 | // copy token
152 | //
153 | token_p = token;
154 |
155 | while ( *script_p > 32 && *script_p != ';')
156 | {
157 | *token_p++ = *script_p++;
158 | if (script_p == scriptend_p)
159 | break;
160 | if (token_p == &token[MAXTOKEN])
161 | Error ("Token too large on line %i\n",scriptline);
162 | }
163 |
164 | *token_p = 0;
165 | return true;
166 | }
167 |
168 |
169 | /*
170 | ==============
171 | =
172 | = TokenAvailable
173 | =
174 | = Returns true if there is another token on the line
175 | =
176 | ==============
177 | */
178 |
179 | qboolean TokenAvailable (void)
180 | {
181 | char *search_p;
182 |
183 | search_p = script_p;
184 |
185 | if (search_p >= scriptend_p)
186 | return false;
187 |
188 | while ( *search_p <= 32)
189 | {
190 | if (*search_p == '\n')
191 | return false;
192 | search_p++;
193 | if (search_p == scriptend_p)
194 | return false;
195 |
196 | }
197 |
198 | if (*search_p == ';')
199 | return false;
200 |
201 | return true;
202 | }
203 |
204 |
205 |
--------------------------------------------------------------------------------
/common/common.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | {743626C6-FD32-4C6D-BA62-F8BEA39F51FD}
38 | Win32Proj
39 | common
40 |
41 |
42 |
43 | StaticLibrary
44 | true
45 | Unicode
46 |
47 |
48 | Application
49 | false
50 | true
51 | Unicode
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | true
65 |
66 |
67 | false
68 |
69 |
70 |
71 |
72 |
73 | Level3
74 | Disabled
75 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
76 |
77 |
78 | Console
79 | true
80 |
81 |
82 |
83 |
84 | Level3
85 |
86 |
87 | MaxSpeed
88 | true
89 | true
90 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
91 |
92 |
93 | Console
94 | true
95 | true
96 | true
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/vis/vis.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | {743626c6-fd32-4c6d-ba62-f8bea39f51fd}
34 |
35 |
36 |
37 | {DD804337-3C39-41C0-B84A-1FF25CF44ADA}
38 | Win32Proj
39 | vis
40 |
41 |
42 |
43 | Application
44 | true
45 | Unicode
46 |
47 |
48 | Application
49 | false
50 | true
51 | Unicode
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | true
65 |
66 |
67 | false
68 |
69 |
70 |
71 |
72 |
73 | Level3
74 | Disabled
75 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
76 | ../common
77 |
78 |
79 | Console
80 | true
81 |
82 |
83 |
84 |
85 | Level3
86 |
87 |
88 | MaxSpeed
89 | true
90 | true
91 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
92 |
93 |
94 | Console
95 | true
96 | true
97 | true
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/qcc/qcc.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {F235A057-0EB0-4AA3-AD00-CB1499C88AF2}
15 | Win32Proj
16 | qcc
17 |
18 |
19 |
20 | Application
21 | true
22 | Unicode
23 |
24 |
25 | Application
26 | false
27 | true
28 | Unicode
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | true
42 |
43 |
44 | false
45 |
46 |
47 |
48 |
49 |
50 | Level3
51 | Disabled
52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
53 | ../common
54 |
55 |
56 | Console
57 | true
58 |
59 |
60 |
61 |
62 | Level3
63 |
64 |
65 | MaxSpeed
66 | true
67 | true
68 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
69 |
70 |
71 | Console
72 | true
73 | true
74 | true
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | {743626c6-fd32-4c6d-ba62-f8bea39f51fd}
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/light/light.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {769A8669-6F8E-4DDE-B5EA-354FCB02415E}
15 | Win32Proj
16 | light
17 |
18 |
19 |
20 | Application
21 | true
22 | Unicode
23 |
24 |
25 | Application
26 | false
27 | true
28 | Unicode
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | true
42 |
43 |
44 | false
45 |
46 |
47 |
48 |
49 |
50 | Level3
51 | Disabled
52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
53 | ..\common
54 |
55 |
56 | Console
57 | true
58 |
59 |
60 |
61 |
62 | Level3
63 |
64 |
65 | MaxSpeed
66 | true
67 | true
68 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
69 |
70 |
71 | Console
72 | true
73 | true
74 | true
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | {743626c6-fd32-4c6d-ba62-f8bea39f51fd}
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/light/trace.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // trace.c
21 |
22 | #include "light.h"
23 |
24 | typedef struct tnode_s
25 | {
26 | int type;
27 | vec3_t normal;
28 | float dist;
29 | int children[2];
30 | int pad;
31 | } tnode_t;
32 |
33 | tnode_t *tnodes, *tnode_p;
34 |
35 | /*
36 | ==============
37 | MakeTnode
38 |
39 | Converts the disk node structure into the efficient tracing structure
40 | ==============
41 | */
42 | void MakeTnode (int nodenum)
43 | {
44 | tnode_t *t;
45 | dplane_t *plane;
46 | int i;
47 | dnode_t *node;
48 |
49 | t = tnode_p++;
50 |
51 | node = dnodes + nodenum;
52 | plane = dplanes + node->planenum;
53 |
54 | t->type = plane->type;
55 | VectorCopy (plane->normal, t->normal);
56 | t->dist = plane->dist;
57 |
58 | for (i=0 ; i<2 ; i++)
59 | {
60 | if (node->children[i] < 0)
61 | t->children[i] = dleafs[-node->children[i] - 1].contents;
62 | else
63 | {
64 | t->children[i] = tnode_p - tnodes;
65 | MakeTnode (node->children[i]);
66 | }
67 | }
68 |
69 | }
70 |
71 |
72 | /*
73 | =============
74 | MakeTnodes
75 |
76 | Loads the node structure out of a .bsp file to be used for light occlusion
77 | =============
78 | */
79 | void MakeTnodes (dmodel_t *bm)
80 | {
81 | tnode_p = tnodes = malloc(numnodes * sizeof(tnode_t));
82 |
83 | MakeTnode (0);
84 | }
85 |
86 |
87 |
88 | /*
89 | ==============================================================================
90 |
91 | LINE TRACING
92 |
93 | The major lighting operation is a point to point visibility test, performed
94 | by recursive subdivision of the line by the BSP tree.
95 |
96 | ==============================================================================
97 | */
98 |
99 | typedef struct
100 | {
101 | vec3_t backpt;
102 | int side;
103 | int node;
104 | } tracestack_t;
105 |
106 |
107 | /*
108 | ==============
109 | TestLine
110 | ==============
111 | */
112 | qboolean TestLine (vec3_t start, vec3_t stop)
113 | {
114 | int node;
115 | float front, back;
116 | tracestack_t *tstack_p;
117 | int side;
118 | float frontx,fronty, frontz, backx, backy, backz;
119 | tracestack_t tracestack[64];
120 | tnode_t *tnode;
121 |
122 | frontx = start[0];
123 | fronty = start[1];
124 | frontz = start[2];
125 | backx = stop[0];
126 | backy = stop[1];
127 | backz = stop[2];
128 |
129 | tstack_p = tracestack;
130 | node = 0;
131 |
132 | while (1)
133 | {
134 | while (node < 0 && node != CONTENTS_SOLID)
135 | {
136 | // pop up the stack for a back side
137 | tstack_p--;
138 | if (tstack_p < tracestack)
139 | return true;
140 | node = tstack_p->node;
141 |
142 | // set the hit point for this plane
143 |
144 | frontx = backx;
145 | fronty = backy;
146 | frontz = backz;
147 |
148 | // go down the back side
149 |
150 | backx = tstack_p->backpt[0];
151 | backy = tstack_p->backpt[1];
152 | backz = tstack_p->backpt[2];
153 |
154 | node = tnodes[tstack_p->node].children[!tstack_p->side];
155 | }
156 |
157 | if (node == CONTENTS_SOLID)
158 | return false; // DONE!
159 |
160 | tnode = &tnodes[node];
161 |
162 | switch (tnode->type)
163 | {
164 | case PLANE_X:
165 | front = frontx - tnode->dist;
166 | back = backx - tnode->dist;
167 | break;
168 | case PLANE_Y:
169 | front = fronty - tnode->dist;
170 | back = backy - tnode->dist;
171 | break;
172 | case PLANE_Z:
173 | front = frontz - tnode->dist;
174 | back = backz - tnode->dist;
175 | break;
176 | default:
177 | front = (frontx*tnode->normal[0] + fronty*tnode->normal[1] + frontz*tnode->normal[2]) - tnode->dist;
178 | back = (backx*tnode->normal[0] + backy*tnode->normal[1] + backz*tnode->normal[2]) - tnode->dist;
179 | break;
180 | }
181 |
182 | if (front > -ON_EPSILON && back > -ON_EPSILON)
183 | // if (front > 0 && back > 0)
184 | {
185 | node = tnode->children[0];
186 | continue;
187 | }
188 |
189 | if (front < ON_EPSILON && back < ON_EPSILON)
190 | // if (front <= 0 && back <= 0)
191 | {
192 | node = tnode->children[1];
193 | continue;
194 | }
195 |
196 | side = front < 0;
197 |
198 | front = front / (front-back);
199 |
200 | tstack_p->node = node;
201 | tstack_p->side = side;
202 | tstack_p->backpt[0] = backx;
203 | tstack_p->backpt[1] = backy;
204 | tstack_p->backpt[2] = backz;
205 |
206 | tstack_p++;
207 |
208 | backx = frontx + front*(backx-frontx);
209 | backy = fronty + front*(backy-fronty);
210 | backz = frontz + front*(backz-frontz);
211 |
212 | node = tnode->children[side];
213 | }
214 | }
215 |
216 |
217 |
--------------------------------------------------------------------------------
/common/trilib.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | //
21 | // trilib.c: library for loading triangles from an Alias triangle file
22 | //
23 |
24 | #include
25 | #include "cmdlib.h"
26 | #include "mathlib.h"
27 | #include "trilib.h"
28 |
29 | // on disk representation of a face
30 |
31 |
32 | #define FLOAT_START 99999.0
33 | #define FLOAT_END -FLOAT_START
34 | #define MAGIC 123322
35 |
36 | //#define NOISY 1
37 |
38 | typedef struct {
39 | float v[3];
40 | } vector;
41 |
42 | typedef struct
43 | {
44 | vector n; /* normal */
45 | vector p; /* point */
46 | vector c; /* color */
47 | float u; /* u */
48 | float v; /* v */
49 | } aliaspoint_t;
50 |
51 | typedef struct {
52 | aliaspoint_t pt[3];
53 | } tf_triangle;
54 |
55 |
56 | void ByteSwapTri (tf_triangle *tri)
57 | {
58 | int i;
59 |
60 | for (i=0 ; iverts[j][k] = tri.pt[j].p.v[k];
175 | }
176 | }
177 |
178 | ptri++;
179 |
180 | if ((ptri - *pptri) >= MAXTRIANGLES)
181 | Error ("Error: too many triangles; increase MAXTRIANGLES\n");
182 | }
183 | }
184 |
185 | *numtriangles = ptri - *pptri;
186 |
187 | fclose (input);
188 | }
189 |
190 |
--------------------------------------------------------------------------------
/qbsp/qbsp.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {21D59AF6-0F02-40E5-B4F7-4CF27D6A8C4F}
15 | Win32Proj
16 | qbsp
17 |
18 |
19 |
20 | Application
21 | true
22 | Unicode
23 |
24 |
25 | Application
26 | false
27 | true
28 | Unicode
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | true
42 |
43 |
44 | false
45 |
46 |
47 |
48 |
49 |
50 | Level3
51 | Disabled
52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
53 | ..\common;%(AdditionalIncludeDirectories)
54 |
55 |
56 | Console
57 | true
58 | %(AdditionalDependencies)
59 |
60 |
61 |
62 |
63 | Level3
64 |
65 |
66 | MaxSpeed
67 | true
68 | true
69 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
70 |
71 |
72 | Console
73 | true
74 | true
75 | true
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | {743626c6-fd32-4c6d-ba62-f8bea39f51fd}
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/common/threads.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #include "cmdlib.h"
22 | #include "threads.h"
23 |
24 | #define MAX_THREADS 64
25 |
26 | int dispatch;
27 | int workcount;
28 | int oldf;
29 | qboolean pacifier;
30 |
31 | /*
32 | =============
33 | GetThreadWork
34 |
35 | =============
36 | */
37 | int GetThreadWork (void)
38 | {
39 | int r;
40 | int f;
41 |
42 | ThreadLock ();
43 |
44 | if (dispatch == workcount)
45 | {
46 | ThreadUnlock ();
47 | return -1;
48 | }
49 |
50 | f = 10*dispatch / workcount;
51 | if (f != oldf)
52 | {
53 | oldf = f;
54 | if (pacifier)
55 | printf ("%i...", f);
56 | }
57 |
58 | r = dispatch;
59 | dispatch++;
60 | ThreadUnlock ();
61 |
62 | return r;
63 | }
64 |
65 |
66 |
67 | /*
68 | ===================================================================
69 |
70 | WIN32
71 |
72 | ===================================================================
73 | */
74 | #ifdef WIN32
75 |
76 | #define USED
77 |
78 | #include
79 |
80 | int numthreads = 1;
81 | CRITICAL_SECTION crit;
82 |
83 | void ThreadLock (void)
84 | {
85 | EnterCriticalSection (&crit);
86 | }
87 |
88 | void ThreadUnlock (void)
89 | {
90 | LeaveCriticalSection (&crit);
91 | }
92 |
93 | /*
94 | =============
95 | RunThreadsOn
96 | =============
97 | */
98 | void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
99 | {
100 | int threadid[MAX_THREADS];
101 | HANDLE threadhandle[MAX_THREADS];
102 | int i;
103 |
104 | dispatch = 0;
105 | workcount = workcnt;
106 | oldf = -1;
107 | pacifier = showpacifier;
108 |
109 | //
110 | // run threads in parallel
111 | //
112 | InitializeCriticalSection (&crit);
113 | for (i=0 ; i
148 |
149 | pthread_mutex_t *my_mutex;
150 |
151 | void ThreadLock (void)
152 | {
153 | if (my_mutex)
154 | pthread_mutex_lock (my_mutex);
155 | }
156 |
157 | void ThreadUnlock (void)
158 | {
159 | if (my_mutex)
160 | pthread_mutex_unlock (my_mutex);
161 | }
162 |
163 |
164 | /*
165 | =============
166 | RunThreadsOn
167 | =============
168 | */
169 | void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
170 | {
171 | int i;
172 | pthread_t work_threads[MAX_THREADS];
173 | pthread_addr_t status;
174 | pthread_attr_t attrib;
175 | pthread_mutexattr_t mattrib;
176 |
177 | dispatch = 0;
178 | workcount = workcnt;
179 | oldf = -1;
180 | pacifier = showpacifier;
181 |
182 | if (!my_mutex)
183 | {
184 | my_mutex = malloc (sizeof(*my_mutex));
185 | if (pthread_mutexattr_create (&mattrib) == -1)
186 | Error ("pthread_mutex_attr_create failed");
187 | if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
188 | Error ("pthread_mutexattr_setkind_np failed");
189 | if (pthread_mutex_init (my_mutex, mattrib) == -1)
190 | Error ("pthread_mutex_init failed");
191 | }
192 |
193 | if (pthread_attr_create (&attrib) == -1)
194 | Error ("pthread_attr_create failed");
195 | if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
196 | Error ("pthread_attr_setstacksize failed");
197 |
198 | for (i=0 ; icontents)
35 | return node;
36 |
37 | d = DotProduct (planes[node->planenum].normal, point) - planes[node->planenum]. dist;
38 |
39 | if (d > 0)
40 | return PointInLeaf (node->children[0], point);
41 |
42 | return PointInLeaf (node->children[1], point);
43 | }
44 |
45 | /*
46 | ===========
47 | PlaceOccupant
48 | ===========
49 | */
50 | qboolean PlaceOccupant (int num, vec3_t point, node_t *headnode)
51 | {
52 | node_t *n;
53 |
54 | n = PointInLeaf (headnode, point);
55 | if (n->contents == CONTENTS_SOLID)
56 | return false;
57 | n->occupied = num;
58 | return true;
59 | }
60 |
61 |
62 | /*
63 | ==============
64 | MarkLeakTrail
65 | ==============
66 | */
67 | portal_t *prevleaknode;
68 | FILE *leakfile;
69 | void MarkLeakTrail (portal_t *n2)
70 | {
71 | int i, j;
72 | vec3_t p1, p2, dir;
73 | float len;
74 | portal_t *n1;
75 |
76 | if (hullnum)
77 | return;
78 |
79 | n1 = prevleaknode;
80 | prevleaknode = n2;
81 |
82 | if (!n1)
83 | return;
84 |
85 | VectorCopy (n2->winding->points[0], p1);
86 | for (i=1 ; i< n2->winding->numpoints ; i++)
87 | {
88 | for (j=0 ; j<3 ; j++)
89 | p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
90 | }
91 |
92 | VectorCopy (n1->winding->points[0], p2);
93 | for (i=1 ; i< n1->winding->numpoints ; i++)
94 | {
95 | for (j=0 ; j<3 ; j++)
96 | p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
97 | }
98 |
99 | VectorSubtract (p2, p1, dir);
100 | len = VectorLength (dir);
101 | VectorNormalize (dir);
102 |
103 | while (len > 2)
104 | {
105 | fprintf (leakfile,"%f %f %f\n", p1[0], p1[1], p1[2]);
106 | for (i=0 ; i<3 ; i++)
107 | p1[i] += dir[i]*2;
108 | len -= 2;
109 | }
110 | }
111 |
112 | /*
113 | ==================
114 | RecursiveFillOutside
115 |
116 | If fill is false, just check, don't fill
117 | Returns true if an occupied leaf is reached
118 | ==================
119 | */
120 | int hit_occupied;
121 | int backdraw;
122 | qboolean RecursiveFillOutside (node_t *l, qboolean fill)
123 | {
124 | portal_t *p;
125 | int s;
126 |
127 | if (l->contents == CONTENTS_SOLID || l->contents == CONTENTS_SKY)
128 | return false;
129 |
130 | if (l->valid == valid)
131 | return false;
132 |
133 | if (l->occupied)
134 | return true;
135 |
136 | l->valid = valid;
137 |
138 | // fill it and it's neighbors
139 | if (fill)
140 | l->contents = CONTENTS_SOLID;
141 | outleafs++;
142 |
143 | for (p=l->portals ; p ; )
144 | {
145 | s = (p->nodes[0] == l);
146 |
147 | if (RecursiveFillOutside (p->nodes[s], fill) )
148 | { // leaked, so stop filling
149 | if (backdraw-- > 0)
150 | {
151 | MarkLeakTrail (p);
152 | DrawLeaf (l, 2);
153 | }
154 | return true;
155 | }
156 | p = p->next[!s];
157 | }
158 |
159 | return false;
160 | }
161 |
162 | /*
163 | ==================
164 | ClearOutFaces
165 |
166 | ==================
167 | */
168 | void ClearOutFaces (node_t *node)
169 | {
170 | face_t **fp;
171 |
172 | if (node->planenum != -1)
173 | {
174 | ClearOutFaces (node->children[0]);
175 | ClearOutFaces (node->children[1]);
176 | return;
177 | }
178 | if (node->contents != CONTENTS_SOLID)
179 | return;
180 |
181 | for (fp=node->markfaces ; *fp ; fp++)
182 | {
183 | // mark all the original faces that are removed
184 | (*fp)->numpoints = 0;
185 | }
186 | node->faces = NULL;
187 | }
188 |
189 |
190 | //=============================================================================
191 |
192 | /*
193 | ===========
194 | FillOutside
195 |
196 | ===========
197 | */
198 | qboolean FillOutside (node_t *node)
199 | {
200 | int s;
201 | vec_t *v;
202 | int i;
203 | qboolean inside;
204 |
205 | qprintf ("----- FillOutside ----\n");
206 |
207 | if (nofill)
208 | {
209 | printf ("skipped\n");
210 | return false;
211 | }
212 |
213 | inside = false;
214 | for (i=1 ; inodes[1] == &outside_node);
230 |
231 | // first check to see if an occupied leaf is hit
232 | outleafs = 0;
233 | valid++;
234 |
235 | prevleaknode = NULL;
236 |
237 | if (!hullnum)
238 | {
239 | leakfile = fopen (pointfilename, "w");
240 | if (!leakfile)
241 | Error ("Couldn't open %s\n", pointfilename);
242 | }
243 |
244 | if (RecursiveFillOutside (outside_node.portals->nodes[s], false))
245 | {
246 | v = entities[hit_occupied].origin;
247 | qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
248 | qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
249 | , v[0], v[1], v[2]);
250 | qprintf ("no filling performed\n");
251 | if (!hullnum)
252 | fclose (leakfile);
253 | qprintf ("leak file written to %s\n", pointfilename);
254 | qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
255 | return false;
256 | }
257 | if (!hullnum)
258 | fclose (leakfile);
259 |
260 | // now go back and fill things in
261 | valid++;
262 | RecursiveFillOutside (outside_node.portals->nodes[s], true);
263 |
264 | // remove faces from filled in leafs
265 | ClearOutFaces (node);
266 |
267 | qprintf ("%4i outleafs\n", outleafs);
268 | return true;
269 | }
270 |
271 |
272 |
--------------------------------------------------------------------------------
/common/bspfile.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 |
22 | // upper design bounds
23 |
24 | #define MAX_MAP_HULLS 4
25 |
26 | #define MAX_MAP_MODELS 256
27 | #define MAX_MAP_BRUSHES 4096
28 | #define MAX_MAP_ENTITIES 1024
29 | #define MAX_MAP_ENTSTRING 65536
30 |
31 | #define MAX_MAP_PLANES 8192
32 | #define MAX_MAP_NODES 32767 // because negative shorts are contents
33 | #define MAX_MAP_CLIPNODES 32767 //
34 | #define MAX_MAP_LEAFS 32767 //
35 | #define MAX_MAP_VERTS 65535
36 | #define MAX_MAP_FACES 65535
37 | #define MAX_MAP_MARKSURFACES 65535
38 | #define MAX_MAP_TEXINFO 4096
39 | #define MAX_MAP_EDGES 256000
40 | #define MAX_MAP_SURFEDGES 512000
41 | #define MAX_MAP_MIPTEX 0x200000
42 | #define MAX_MAP_LIGHTING 0x100000
43 | #define MAX_MAP_VISIBILITY 0x100000
44 |
45 | // key / value pair sizes
46 |
47 | #define MAX_KEY 32
48 | #define MAX_VALUE 1024
49 |
50 | //=============================================================================
51 |
52 |
53 | #define BSPVERSION 29
54 |
55 | typedef struct
56 | {
57 | int fileofs, filelen;
58 | } lump_t;
59 |
60 | #define LUMP_ENTITIES 0
61 | #define LUMP_PLANES 1
62 | #define LUMP_TEXTURES 2
63 | #define LUMP_VERTEXES 3
64 | #define LUMP_VISIBILITY 4
65 | #define LUMP_NODES 5
66 | #define LUMP_TEXINFO 6
67 | #define LUMP_FACES 7
68 | #define LUMP_LIGHTING 8
69 | #define LUMP_CLIPNODES 9
70 | #define LUMP_LEAFS 10
71 | #define LUMP_MARKSURFACES 11
72 | #define LUMP_EDGES 12
73 | #define LUMP_SURFEDGES 13
74 | #define LUMP_MODELS 14
75 |
76 | #define HEADER_LUMPS 15
77 |
78 | typedef struct
79 | {
80 | float mins[3], maxs[3];
81 | float origin[3];
82 | int headnode[MAX_MAP_HULLS];
83 | int visleafs; // not including the solid leaf 0
84 | int firstface, numfaces;
85 | } dmodel_t;
86 |
87 | typedef struct
88 | {
89 | int version;
90 | lump_t lumps[HEADER_LUMPS];
91 | } dheader_t;
92 |
93 | typedef struct
94 | {
95 | int nummiptex;
96 | int dataofs[4]; // [nummiptex]
97 | } dmiptexlump_t;
98 |
99 | #define MIPLEVELS 4
100 | typedef struct miptex_s
101 | {
102 | char name[16];
103 | unsigned width, height;
104 | unsigned offsets[MIPLEVELS]; // four mip maps stored
105 | } miptex_t;
106 |
107 |
108 | typedef struct
109 | {
110 | float point[3];
111 | } dvertex_t;
112 |
113 |
114 | // 0-2 are axial planes
115 | #define PLANE_X 0
116 | #define PLANE_Y 1
117 | #define PLANE_Z 2
118 |
119 | // 3-5 are non-axial planes snapped to the nearest
120 | #define PLANE_ANYX 3
121 | #define PLANE_ANYY 4
122 | #define PLANE_ANYZ 5
123 |
124 | typedef struct
125 | {
126 | float normal[3];
127 | float dist;
128 | int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
129 | } dplane_t;
130 |
131 |
132 |
133 | #define CONTENTS_EMPTY -1
134 | #define CONTENTS_SOLID -2
135 | #define CONTENTS_WATER -3
136 | #define CONTENTS_SLIME -4
137 | #define CONTENTS_LAVA -5
138 | #define CONTENTS_SKY -6
139 |
140 | // !!! if this is changed, it must be changed in asm_i386.h too !!!
141 | typedef struct
142 | {
143 | int planenum;
144 | short children[2]; // negative numbers are -(leafs+1), not nodes
145 | short mins[3]; // for sphere culling
146 | short maxs[3];
147 | unsigned short firstface;
148 | unsigned short numfaces; // counting both sides
149 | } dnode_t;
150 |
151 | typedef struct
152 | {
153 | int planenum;
154 | short children[2]; // negative numbers are contents
155 | } dclipnode_t;
156 |
157 |
158 | typedef struct texinfo_s
159 | {
160 | float vecs[2][4]; // [s/t][xyz offset]
161 | int miptex;
162 | int flags;
163 | } texinfo_t;
164 | #define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
165 |
166 | // note that edge 0 is never used, because negative edge nums are used for
167 | // counterclockwise use of the edge in a face
168 | typedef struct
169 | {
170 | unsigned short v[2]; // vertex numbers
171 | } dedge_t;
172 |
173 | #define MAXLIGHTMAPS 4
174 | typedef struct
175 | {
176 | short planenum;
177 | short side;
178 |
179 | int firstedge; // we must support > 64k edges
180 | short numedges;
181 | short texinfo;
182 |
183 | // lighting info
184 | byte styles[MAXLIGHTMAPS];
185 | int lightofs; // start of [numstyles*surfsize] samples
186 | } dface_t;
187 |
188 |
189 |
190 | #define AMBIENT_WATER 0
191 | #define AMBIENT_SKY 1
192 | #define AMBIENT_SLIME 2
193 | #define AMBIENT_LAVA 3
194 |
195 | #define NUM_AMBIENTS 4 // automatic ambient sounds
196 |
197 | // leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
198 | // all other leafs need visibility info
199 | typedef struct
200 | {
201 | int contents;
202 | int visofs; // -1 = no visibility info
203 |
204 | short mins[3]; // for frustum culling
205 | short maxs[3];
206 |
207 | unsigned short firstmarksurface;
208 | unsigned short nummarksurfaces;
209 |
210 | byte ambient_level[NUM_AMBIENTS];
211 | } dleaf_t;
212 |
213 | //============================================================================
214 |
215 | #ifndef QUAKE_GAME
216 |
217 | // the utilities get to be lazy and just use large static arrays
218 |
219 | extern int nummodels;
220 | extern dmodel_t dmodels[MAX_MAP_MODELS];
221 |
222 | extern int visdatasize;
223 | extern byte dvisdata[MAX_MAP_VISIBILITY];
224 |
225 | extern int lightdatasize;
226 | extern byte dlightdata[MAX_MAP_LIGHTING];
227 |
228 | extern int texdatasize;
229 | extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
230 |
231 | extern int entdatasize;
232 | extern char dentdata[MAX_MAP_ENTSTRING];
233 |
234 | extern int numleafs;
235 | extern dleaf_t dleafs[MAX_MAP_LEAFS];
236 |
237 | extern int numplanes;
238 | extern dplane_t dplanes[MAX_MAP_PLANES];
239 |
240 | extern int numvertexes;
241 | extern dvertex_t dvertexes[MAX_MAP_VERTS];
242 |
243 | extern int numnodes;
244 | extern dnode_t dnodes[MAX_MAP_NODES];
245 |
246 | extern int numtexinfo;
247 | extern texinfo_t texinfo[MAX_MAP_TEXINFO];
248 |
249 | extern int numfaces;
250 | extern dface_t dfaces[MAX_MAP_FACES];
251 |
252 | extern int numclipnodes;
253 | extern dclipnode_t dclipnodes[MAX_MAP_CLIPNODES];
254 |
255 | extern int numedges;
256 | extern dedge_t dedges[MAX_MAP_EDGES];
257 |
258 | extern int nummarksurfaces;
259 | extern unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES];
260 |
261 | extern int numsurfedges;
262 | extern int dsurfedges[MAX_MAP_SURFEDGES];
263 |
264 |
265 |
266 | void LoadBSPFile (char *filename);
267 | void WriteBSPFile (char *filename);
268 | void PrintBSPFileSizes (void);
269 |
270 | #endif
271 |
--------------------------------------------------------------------------------
/qbsp/merge.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // merge.c
21 |
22 | #include "bsp5.h"
23 |
24 |
25 | #define CONTINUOUS_EPSILON 0.001
26 |
27 | /*
28 | ================
29 | CheckColinear
30 |
31 | ================
32 | */
33 | void CheckColinear (face_t *f)
34 | {
35 | int i, j;
36 | vec3_t v1, v2;
37 |
38 | for (i=0 ; inumpoints ;i++)
39 | {
40 | // skip the point if the vector from the previous point is the same
41 | // as the vector to the next point
42 | j = (i - 1 < 0) ? f->numpoints - 1 : i - 1;
43 | VectorSubtract (f->pts[i], f->pts[j], v1);
44 | VectorNormalize (v1);
45 |
46 | j = (i + 1 == f->numpoints) ? 0 : i + 1;
47 | VectorSubtract (f->pts[j], f->pts[i], v2);
48 | VectorNormalize (v2);
49 |
50 | if (VectorCompare (v1, v2))
51 | Error ("Colinear edge");
52 | }
53 |
54 | }
55 |
56 |
57 | /*
58 | =============
59 | TryMerge
60 |
61 | If two polygons share a common edge and the edges that meet at the
62 | common points are both inside the other polygons, merge them
63 |
64 | Returns NULL if the faces couldn't be merged, or the new face.
65 | The originals will NOT be freed.
66 | =============
67 | */
68 | face_t *TryMerge (face_t *f1, face_t *f2)
69 | {
70 | vec_t *p1, *p2, *p3, *p4, *back;
71 | face_t *newf;
72 | int i, j, k, l;
73 | vec3_t normal, delta, planenormal;
74 | vec_t dot;
75 | plane_t *plane;
76 | qboolean keep1, keep2;
77 |
78 | if (f1->numpoints == -1 || f2->numpoints == -1)
79 | return NULL;
80 | if (f1->planeside != f2->planeside)
81 | return NULL;
82 | if (f1->texturenum != f2->texturenum)
83 | return NULL;
84 | if (f1->contents[0] != f2->contents[0])
85 | return NULL;
86 | if (f1->contents[1] != f2->contents[1])
87 | return NULL;
88 |
89 | //
90 | // find a common edge
91 | //
92 | p1 = p2 = NULL; // stop compiler warning
93 | j = 0; //
94 |
95 | for (i=0 ; inumpoints ; i++)
96 | {
97 | p1 = f1->pts[i];
98 | p2 = f1->pts[(i+1)%f1->numpoints];
99 | for (j=0 ; jnumpoints ; j++)
100 | {
101 | p3 = f2->pts[j];
102 | p4 = f2->pts[(j+1)%f2->numpoints];
103 | for (k=0 ; k<3 ; k++)
104 | {
105 | if (fabs(p1[k] - p4[k]) > EQUAL_EPSILON)
106 | break;
107 | if (fabs(p2[k] - p3[k]) > EQUAL_EPSILON)
108 | break;
109 | }
110 | if (k==3)
111 | break;
112 | }
113 | if (j < f2->numpoints)
114 | break;
115 | }
116 |
117 | if (i == f1->numpoints)
118 | return NULL; // no matching edges
119 |
120 | //
121 | // check slope of connected lines
122 | // if the slopes are colinear, the point can be removed
123 | //
124 | plane = &planes[f1->planenum];
125 | VectorCopy (plane->normal, planenormal);
126 | if (f1->planeside)
127 | VectorSubtract (vec3_origin, planenormal, planenormal);
128 |
129 | back = f1->pts[(i+f1->numpoints-1)%f1->numpoints];
130 | VectorSubtract (p1, back, delta);
131 | CrossProduct (planenormal, delta, normal);
132 | VectorNormalize (normal);
133 |
134 | back = f2->pts[(j+2)%f2->numpoints];
135 | VectorSubtract (back, p1, delta);
136 | dot = DotProduct (delta, normal);
137 | if (dot > CONTINUOUS_EPSILON)
138 | return NULL; // not a convex polygon
139 | keep1 = dot < -CONTINUOUS_EPSILON;
140 |
141 | back = f1->pts[(i+2)%f1->numpoints];
142 | VectorSubtract (back, p2, delta);
143 | CrossProduct (planenormal, delta, normal);
144 | VectorNormalize (normal);
145 |
146 | back = f2->pts[(j+f2->numpoints-1)%f2->numpoints];
147 | VectorSubtract (back, p2, delta);
148 | dot = DotProduct (delta, normal);
149 | if (dot > CONTINUOUS_EPSILON)
150 | return NULL; // not a convex polygon
151 | keep2 = dot < -CONTINUOUS_EPSILON;
152 |
153 | //
154 | // build the new polygon
155 | //
156 | if (f1->numpoints + f2->numpoints > MAXEDGES)
157 | {
158 | // Error ("TryMerge: too many edges!");
159 | return NULL;
160 | }
161 |
162 | newf = NewFaceFromFace (f1);
163 |
164 | // copy first polygon
165 | for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints)
166 | {
167 | if (k==(i+1)%f1->numpoints && !keep2)
168 | continue;
169 |
170 | VectorCopy (f1->pts[k], newf->pts[newf->numpoints]);
171 | newf->numpoints++;
172 | }
173 |
174 | // copy second polygon
175 | for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints)
176 | {
177 | if (l==(j+1)%f2->numpoints && !keep1)
178 | continue;
179 | VectorCopy (f2->pts[l], newf->pts[newf->numpoints]);
180 | newf->numpoints++;
181 | }
182 |
183 | return newf;
184 | }
185 |
186 |
187 | /*
188 | ===============
189 | MergeFaceToList
190 | ===============
191 | */
192 | qboolean mergedebug;
193 | face_t *MergeFaceToList (face_t *face, face_t *list)
194 | {
195 | face_t *newf, *f;
196 |
197 | for (f=list ; f ; f=f->next)
198 | {
199 | //CheckColinear (f);
200 | if (mergedebug)
201 | {
202 | Draw_ClearWindow ();
203 | Draw_DrawFace (face);
204 | Draw_DrawFace (f);
205 | Draw_SetBlack ();
206 | }
207 | newf = TryMerge (face, f);
208 | if (!newf)
209 | continue;
210 | FreeFace (face);
211 | f->numpoints = -1; // merged out
212 | return MergeFaceToList (newf, list);
213 | }
214 |
215 | // didn't merge, so add at start
216 | face->next = list;
217 | return face;
218 | }
219 |
220 |
221 | /*
222 | ===============
223 | FreeMergeListScraps
224 | ===============
225 | */
226 | face_t *FreeMergeListScraps (face_t *merged)
227 | {
228 | face_t *head, *next;
229 |
230 | head = NULL;
231 | for ( ; merged ; merged = next)
232 | {
233 | next = merged->next;
234 | if (merged->numpoints == -1)
235 | FreeFace (merged);
236 | else
237 | {
238 | merged->next = head;
239 | head = merged;
240 | }
241 | }
242 |
243 | return head;
244 | }
245 |
246 |
247 | /*
248 | ===============
249 | MergePlaneFaces
250 | ===============
251 | */
252 | void MergePlaneFaces (surface_t *plane)
253 | {
254 | face_t *f1, *next;
255 | face_t *merged;
256 |
257 | merged = NULL;
258 |
259 | for (f1 = plane->faces ; f1 ; f1 = next)
260 | {
261 | next = f1->next;
262 | merged = MergeFaceToList (f1, merged);
263 | }
264 |
265 | // chain all of the non-empty faces to the plane
266 | plane->faces = FreeMergeListScraps (merged);
267 | }
268 |
269 |
270 | /*
271 | ============
272 | MergeAll
273 | ============
274 | */
275 | void MergeAll (surface_t *surfhead)
276 | {
277 | surface_t *surf;
278 | int mergefaces;
279 | face_t *f;
280 |
281 | printf ("---- MergeAll ----\n");
282 |
283 | mergefaces = 0;
284 | for (surf = surfhead ; surf ; surf=surf->next)
285 | {
286 | MergePlaneFaces (surf);
287 | Draw_ClearWindow ();
288 | for (f=surf->faces ; f ; f=f->next)
289 | {
290 | Draw_DrawFace (f);
291 | mergefaces++;
292 | }
293 | }
294 |
295 | printf ("%i mergefaces\n", mergefaces);
296 | }
297 |
--------------------------------------------------------------------------------
/qc/subs.qc:
--------------------------------------------------------------------------------
1 | /*
2 | subs.qc
3 |
4 | sub-functions, mostly movement related
5 |
6 | Copyright (C) 1996-1997 Id Software, Inc.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 |
17 | See the GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to:
21 |
22 | Free Software Foundation, Inc.
23 | 59 Temple Place - Suite 330
24 | Boston, MA 02111-1307, USA
25 |
26 | */
27 |
28 |
29 | void() SUB_Null = {};
30 |
31 | void() SUB_Remove = {remove(self);};
32 |
33 |
34 | /*
35 | QuakeEd only writes a single float for angles (bad idea), so up and down are
36 | just constant angles.
37 | */
38 | vector() SetMovedir =
39 | {
40 | if (self.angles == '0 -1 0')
41 | self.movedir = '0 0 1';
42 | else if (self.angles == '0 -2 0')
43 | self.movedir = '0 0 -1';
44 | else
45 | {
46 | makevectors (self.angles);
47 | self.movedir = v_forward;
48 | }
49 |
50 | self.angles = '0 0 0';
51 | };
52 |
53 | /*
54 | ================
55 | InitTrigger
56 | ================
57 | */
58 | void() InitTrigger =
59 | {
60 | // trigger angles are used for one-way touches. An angle of 0 is assumed
61 | // to mean no restrictions, so use a yaw of 360 instead.
62 | if (self.angles != '0 0 0')
63 | SetMovedir ();
64 | self.solid = SOLID_TRIGGER;
65 | setmodel (self, self.model); // set size and link into world
66 | self.movetype = MOVETYPE_NONE;
67 | self.modelindex = 0;
68 | self.model = "";
69 | };
70 |
71 | /*
72 | =============
73 | SUB_CalcMove
74 |
75 | calculate self.velocity and self.nextthink to reach dest from
76 | self.origin traveling at speed
77 | ===============
78 | */
79 | void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
80 | {
81 | local entity stemp;
82 | stemp = self;
83 | self = ent;
84 |
85 | SUB_CalcMove (tdest, tspeed, func);
86 | self = stemp;
87 | };
88 |
89 | void(vector tdest, float tspeed, void() func) SUB_CalcMove =
90 | {
91 | local vector vdestdelta;
92 | local float len, traveltime;
93 |
94 | if (!tspeed)
95 | objerror("No speed is defined!");
96 |
97 | self.think1 = func;
98 | self.finaldest = tdest;
99 | self.think = SUB_CalcMoveDone;
100 |
101 | if (tdest == self.origin)
102 | {
103 | self.velocity = '0 0 0';
104 | self.nextthink = self.ltime + 0.1;
105 | return;
106 | }
107 |
108 | // set destdelta to the vector needed to move
109 | vdestdelta = tdest - self.origin;
110 |
111 | // calculate length of vector
112 | len = vlen (vdestdelta);
113 |
114 | // divide by speed to get time to reach dest
115 | traveltime = len / tspeed;
116 |
117 | if (traveltime < 0.03)
118 | traveltime = 0.03;
119 |
120 | // set nextthink to trigger a think when dest is reached
121 | self.nextthink = self.ltime + traveltime;
122 |
123 | // scale the destdelta vector by the time spent traveling to get velocity
124 | self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
125 | };
126 |
127 | /*
128 | ============
129 | After moving, set origin to exact final destination
130 | ============
131 | */
132 | void() SUB_CalcMoveDone =
133 | {
134 | setorigin(self, self.finaldest);
135 | self.velocity = '0 0 0';
136 | self.nextthink = -1;
137 | if (self.think1)
138 | self.think1();
139 | };
140 |
141 |
142 | /*
143 | =============
144 | SUB_CalcAngleMove
145 |
146 | calculate self.avelocity and self.nextthink to reach destangle from
147 | self.angles rotating
148 |
149 | The calling function should make sure self.think is valid
150 | ===============
151 | */
152 | void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
153 | {
154 | local entity stemp;
155 | stemp = self;
156 | self = ent;
157 | SUB_CalcAngleMove (destangle, tspeed, func);
158 | self = stemp;
159 | };
160 |
161 | void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
162 | {
163 | local vector destdelta;
164 | local float len, traveltime;
165 |
166 | if (!tspeed)
167 | objerror("No speed is defined!");
168 |
169 | // set destdelta to the vector needed to move
170 | destdelta = destangle - self.angles;
171 |
172 | // calculate length of vector
173 | len = vlen (destdelta);
174 |
175 | // divide by speed to get time to reach dest
176 | traveltime = len / tspeed;
177 |
178 | // set nextthink to trigger a think when dest is reached
179 | self.nextthink = self.ltime + traveltime;
180 |
181 | // scale the destdelta vector by the time spent traveling to get velocity
182 | self.avelocity = destdelta * (1 / traveltime);
183 |
184 | self.think1 = func;
185 | self.finalangle = destangle;
186 | self.think = SUB_CalcAngleMoveDone;
187 | };
188 |
189 | /*
190 | ============
191 | After rotating, set angle to exact final angle
192 | ============
193 | */
194 | void() SUB_CalcAngleMoveDone =
195 | {
196 | self.angles = self.finalangle;
197 | self.avelocity = '0 0 0';
198 | self.nextthink = -1;
199 | if (self.think1)
200 | self.think1();
201 | };
202 |
203 |
204 | //=============================================================================
205 |
206 | void() DelayThink =
207 | {
208 | activator = self.enemy;
209 | SUB_UseTargets ();
210 | remove(self);
211 | };
212 |
213 | /*
214 | ==============================
215 | SUB_UseTargets
216 |
217 | the global "activator" should be set to the entity that initiated the firing.
218 |
219 | If self.delay is set, a DelayedUse entity will be created that will actually
220 | do the SUB_UseTargets after that many seconds have passed.
221 |
222 | Centerprints any self.message to the activator.
223 |
224 | Removes all entities with a targetname that match self.killtarget,
225 | and removes them, so some events can remove other triggers.
226 |
227 | Search for (string)targetname in all entities that
228 | match (string)self.target and call their .use function
229 |
230 | ==============================
231 | */
232 | void() SUB_UseTargets =
233 | {
234 | local entity t, stemp, otemp, act;
235 |
236 | //
237 | // check for a delay
238 | //
239 | if (self.delay)
240 | {
241 | // create a temp object to fire at a later time
242 | t = spawn();
243 | t.classname = "DelayedUse";
244 | t.nextthink = time + self.delay;
245 | t.think = DelayThink;
246 | t.enemy = activator;
247 | t.message = self.message;
248 | t.killtarget = self.killtarget;
249 | t.target = self.target;
250 | return;
251 | }
252 |
253 |
254 | //
255 | // print the message
256 | //
257 | if (activator.classname == "player" && self.message != "")
258 | {
259 | centerprint (activator, self.message);
260 | if (!self.noise)
261 | sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
262 | }
263 |
264 | //
265 | // kill the killtagets
266 | //
267 | if (self.killtarget)
268 | {
269 | t = world;
270 | do
271 | {
272 | t = find (t, targetname, self.killtarget);
273 | if (!t)
274 | return;
275 | remove (t);
276 | } while ( 1 );
277 | }
278 |
279 | //
280 | // fire targets
281 | //
282 | if (self.target)
283 | {
284 | act = activator;
285 | t = world;
286 | do
287 | {
288 | t = find (t, targetname, self.target);
289 | if (!t)
290 | {
291 | return;
292 | }
293 | stemp = self;
294 | otemp = other;
295 | self = t;
296 | other = stemp;
297 | if (self.use != SUB_Null)
298 | {
299 | if (self.use)
300 | self.use ();
301 | }
302 | self = stemp;
303 | other = otemp;
304 | activator = act;
305 | } while ( 1 );
306 | }
307 |
308 |
309 | };
310 |
311 |
--------------------------------------------------------------------------------
/common/wadlib.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // wad2lib.c
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | //#include
30 | #include
31 |
32 | #ifdef NeXT
33 | #include
34 | #endif
35 | #include "cmdlib.h"
36 | #include "wadlib.h"
37 |
38 | /*
39 | ============================================================================
40 |
41 | WAD READING
42 |
43 | ============================================================================
44 | */
45 |
46 |
47 | lumpinfo_t *lumpinfo; // location of each lump on disk
48 | int numlumps;
49 |
50 | wadinfo_t header;
51 | FILE *wadhandle;
52 |
53 |
54 | /*
55 | ====================
56 | W_OpenWad
57 | ====================
58 | */
59 | void W_OpenWad (char *filename)
60 | {
61 | lumpinfo_t *lump_p;
62 | unsigned i;
63 | int length;
64 |
65 | //
66 | // open the file and add to directory
67 | //
68 | wadhandle = SafeOpenRead (filename);
69 | SafeRead (wadhandle, &header, sizeof(header));
70 |
71 | if (strncmp(header.identification,"WAD2",4))
72 | Error ("Wad file %s doesn't have WAD2 id\n",filename);
73 |
74 | header.numlumps = LittleLong(header.numlumps);
75 | header.infotableofs = LittleLong(header.infotableofs);
76 |
77 | numlumps = header.numlumps;
78 |
79 | length = numlumps*sizeof(lumpinfo_t);
80 | lumpinfo = malloc (length);
81 | lump_p = lumpinfo;
82 |
83 | fseek (wadhandle, header.infotableofs, SEEK_SET);
84 | SafeRead (wadhandle, lumpinfo, length);
85 |
86 | //
87 | // Fill in lumpinfo
88 | //
89 |
90 | for (i=0 ; ifilepos = LittleLong(lump_p->filepos);
93 | lump_p->size = LittleLong(lump_p->size);
94 | }
95 | }
96 |
97 |
98 |
99 | void CleanupName (char *in, char *out)
100 | {
101 | int i;
102 |
103 | for (i=0 ; iname ) ; i++ )
104 | {
105 | if (!in[i])
106 | break;
107 |
108 | out[i] = toupper(in[i]);
109 | }
110 |
111 | for ( ; iname ); i++ )
112 | out[i] = 0;
113 | }
114 |
115 |
116 | /*
117 | ====================
118 | W_CheckNumForName
119 |
120 | Returns -1 if name not found
121 | ====================
122 | */
123 | int W_CheckNumForName (char *name)
124 | {
125 | char cleanname[16];
126 | int v1,v2, v3, v4;
127 | int i;
128 | lumpinfo_t *lump_p;
129 |
130 | CleanupName (name, cleanname);
131 |
132 | // make the name into four integers for easy compares
133 |
134 | v1 = *(int *)cleanname;
135 | v2 = *(int *)&cleanname[4];
136 | v3 = *(int *)&cleanname[8];
137 | v4 = *(int *)&cleanname[12];
138 |
139 | // find it
140 |
141 | lump_p = lumpinfo;
142 | for (i=0 ; iname == v1
145 | && *(int *)&lump_p->name[4] == v2
146 | && *(int *)&lump_p->name[8] == v3
147 | && *(int *)&lump_p->name[12] == v4)
148 | return i;
149 | }
150 |
151 | return -1;
152 | }
153 |
154 |
155 | /*
156 | ====================
157 | W_GetNumForName
158 |
159 | Calls W_CheckNumForName, but bombs out if not found
160 | ====================
161 | */
162 | int W_GetNumForName (char *name)
163 | {
164 | int i;
165 |
166 | i = W_CheckNumForName (name);
167 | if (i != -1)
168 | return i;
169 |
170 | Error ("W_GetNumForName: %s not found!",name);
171 | return -1;
172 | }
173 |
174 |
175 | /*
176 | ====================
177 | W_LumpLength
178 |
179 | Returns the buffer size needed to load the given lump
180 | ====================
181 | */
182 | int W_LumpLength (int lump)
183 | {
184 | if (lump >= numlumps)
185 | Error ("W_LumpLength: %i >= numlumps",lump);
186 | return lumpinfo[lump].size;
187 | }
188 |
189 |
190 | /*
191 | ====================
192 | W_ReadLumpNum
193 |
194 | Loads the lump into the given buffer, which must be >= W_LumpLength()
195 | ====================
196 | */
197 | void W_ReadLumpNum (int lump, void *dest)
198 | {
199 | lumpinfo_t *l;
200 |
201 | if (lump >= numlumps)
202 | Error ("W_ReadLump: %i >= numlumps",lump);
203 | l = lumpinfo+lump;
204 |
205 | fseek (wadhandle, l->filepos, SEEK_SET);
206 | SafeRead (wadhandle, dest, l->size);
207 | }
208 |
209 |
210 |
211 | /*
212 | ====================
213 | W_LoadLumpNum
214 | ====================
215 | */
216 | void *W_LoadLumpNum (int lump)
217 | {
218 | void *buf;
219 |
220 | if ((unsigned)lump >= numlumps)
221 | Error ("W_CacheLumpNum: %i >= numlumps",lump);
222 |
223 | buf = malloc (W_LumpLength (lump));
224 | W_ReadLumpNum (lump, buf);
225 |
226 | return buf;
227 | }
228 |
229 |
230 | /*
231 | ====================
232 | W_LoadLumpName
233 | ====================
234 | */
235 | void *W_LoadLumpName (char *name)
236 | {
237 | return W_LoadLumpNum (W_GetNumForName(name));
238 | }
239 |
240 |
241 | /*
242 | ===============================================================================
243 |
244 | WAD CREATION
245 |
246 | ===============================================================================
247 | */
248 |
249 | FILE *outwad;
250 |
251 | lumpinfo_t outinfo[4096];
252 | int outlumps;
253 |
254 | short (*wadshort) (short l);
255 | int (*wadlong) (int l);
256 |
257 | /*
258 | ===============
259 | NewWad
260 | ===============
261 | */
262 |
263 | void NewWad (char *pathname, qboolean bigendien)
264 | {
265 | outwad = SafeOpenWrite (pathname);
266 | fseek (outwad, sizeof(wadinfo_t), SEEK_SET);
267 | memset (outinfo, 0, sizeof(outinfo));
268 |
269 | if (bigendien)
270 | {
271 | wadshort = BigShort;
272 | wadlong = BigLong;
273 | }
274 | else
275 | {
276 | wadshort = LittleShort;
277 | wadlong = LittleLong;
278 | }
279 |
280 | outlumps = 0;
281 | }
282 |
283 |
284 | /*
285 | ===============
286 | AddLump
287 | ===============
288 | */
289 |
290 | void AddLump (char *name, void *buffer, int length, int type, int compress)
291 | {
292 | lumpinfo_t *info;
293 | int ofs;
294 |
295 | info = &outinfo[outlumps];
296 | outlumps++;
297 |
298 | memset (info,0,sizeof(info));
299 |
300 | strcpy (info->name, name);
301 | strupr (info->name);
302 |
303 | ofs = ftell(outwad);
304 | info->filepos = wadlong(ofs);
305 | info->size = info->disksize = wadlong(length);
306 | info->type = type;
307 | info->compression = compress;
308 |
309 | // FIXME: do compression
310 |
311 | SafeWrite (outwad, buffer, length);
312 | }
313 |
314 |
315 | /*
316 | ===============
317 | WriteWad
318 | ===============
319 | */
320 |
321 | void WriteWad (void)
322 | {
323 | wadinfo_t header;
324 | int ofs;
325 |
326 | // write the lumpingo
327 | ofs = ftell(outwad);
328 |
329 | SafeWrite (outwad, outinfo, outlumps*sizeof(lumpinfo_t) );
330 |
331 | // write the header
332 |
333 | // a program will be able to tell the ednieness of a wad by the id
334 | header.identification[0] = 'W';
335 | header.identification[1] = 'A';
336 | header.identification[2] = 'D';
337 | header.identification[3] = '2';
338 |
339 | header.numlumps = wadlong(outlumps);
340 | header.infotableofs = wadlong(ofs);
341 |
342 | fseek (outwad, 0, SEEK_SET);
343 | SafeWrite (outwad, &header, sizeof(header));
344 | fclose (outwad);
345 | }
346 |
347 |
348 |
--------------------------------------------------------------------------------
/light/entities.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 | // entities.c
21 |
22 | #include "light.h"
23 |
24 | entity_t entities[MAX_MAP_ENTITIES];
25 | int num_entities;
26 |
27 | /*
28 | ==============================================================================
29 |
30 | ENTITY FILE PARSING
31 |
32 | If a light has a targetname, generate a unique style in the 32-63 range
33 | ==============================================================================
34 | */
35 |
36 | int numlighttargets;
37 | char lighttargets[32][64];
38 |
39 | int LightStyleForTargetname (char *targetname, qboolean alloc)
40 | {
41 | int i;
42 |
43 | for (i=0 ; ikey, key);
152 | strcpy (epair->value, com_token);
153 | epair->next = entity->epairs;
154 | entity->epairs = epair;
155 |
156 | if (!strcmp(key, "classname"))
157 | strcpy (entity->classname, com_token);
158 | else if (!strcmp(key, "target"))
159 | strcpy (entity->target, com_token);
160 | else if (!strcmp(key, "targetname"))
161 | strcpy (entity->targetname, com_token);
162 | else if (!strcmp(key, "origin"))
163 | {
164 | // scan into doubles, then assign
165 | // which makes it vec_t size independent
166 | if (sscanf(com_token, "%lf %lf %lf",
167 | &vec[0], &vec[1], &vec[2]) != 3)
168 | Error ("LoadEntities: not 3 values for origin");
169 | for (i=0 ; i<3 ; i++)
170 | entity->origin[i] = vec[i];
171 | }
172 | else if (!strncmp(key, "light", 5) || !strcmp (key, "_light") )
173 | {
174 | entity->light = atof(com_token);
175 | }
176 | else if (!strcmp(key, "style"))
177 | {
178 | entity->style = atof(com_token);
179 | if ((unsigned)entity->style > 254)
180 | Error ("Bad light style %i (must be 0-254)", entity->style);
181 | }
182 | else if (!strcmp(key, "angle"))
183 | {
184 | entity->angle = atof(com_token);
185 | }
186 |
187 | }
188 |
189 | // all fields have been parsed
190 | if (!strncmp (entity->classname, "light", 5) && !entity->light)
191 | entity->light = DEFAULTLIGHTLEVEL;
192 |
193 | if (!strcmp (entity->classname, "light"))
194 | {
195 | if (entity->targetname[0] && !entity->style)
196 | {
197 | char s[16];
198 |
199 | entity->style = LightStyleForTargetname (entity->targetname, true);
200 | sprintf (s,"%i", entity->style);
201 | SetKeyValue (entity, "style", s);
202 | }
203 | }
204 | }
205 |
206 | printf ("%d entities read\n", num_entities);
207 |
208 | MatchTargets ();
209 | }
210 |
211 | char *ValueForKey (entity_t *ent, char *key)
212 | {
213 | epair_t *ep;
214 |
215 | for (ep=ent->epairs ; ep ; ep=ep->next)
216 | if (!strcmp (ep->key, key) )
217 | return ep->value;
218 | return "";
219 | }
220 |
221 | void SetKeyValue (entity_t *ent, char *key, char *value)
222 | {
223 | epair_t *ep;
224 |
225 | for (ep=ent->epairs ; ep ; ep=ep->next)
226 | if (!strcmp (ep->key, key) )
227 | {
228 | strcpy (ep->value, value);
229 | return;
230 | }
231 | ep = malloc (sizeof(*ep));
232 | ep->next = ent->epairs;
233 | ent->epairs = ep;
234 | strcpy (ep->key, key);
235 | strcpy (ep->value, value);
236 | }
237 |
238 | float FloatForKey (entity_t *ent, char *key)
239 | {
240 | char *k;
241 |
242 | k = ValueForKey (ent, key);
243 | return atof(k);
244 | }
245 |
246 | void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
247 | {
248 | char *k;
249 |
250 | k = ValueForKey (ent, key);
251 | sscanf (k, "%lf %lf %lf", &vec[0], &vec[1], &vec[2]);
252 | }
253 |
254 |
255 |
256 | /*
257 | ================
258 | WriteEntitiesToString
259 | ================
260 | */
261 | void WriteEntitiesToString (void)
262 | {
263 | char *buf, *end;
264 | epair_t *ep;
265 | char line[128];
266 | int i;
267 |
268 | buf = dentdata;
269 | end = buf;
270 | *end = 0;
271 |
272 | printf ("%i switchable light styles\n", numlighttargets);
273 |
274 | for (i=0 ; inext)
284 | {
285 | sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
286 | strcat (end, line);
287 | end += strlen(line);
288 | }
289 | strcat (end,"}\n");
290 | end += 2;
291 |
292 | if (end > buf + MAX_MAP_ENTSTRING)
293 | Error ("Entity text too long");
294 | }
295 | entdatasize = end - buf + 1;
296 | }
297 |
298 |
--------------------------------------------------------------------------------
/comments/text.txt:
--------------------------------------------------------------------------------
1 | Overall the code is painful to read:
2 |
3 | - Very few comments
4 | - Some comments are outdated.
5 | - The internal functionment of some function is determined by global variables. This makes is very difficult to keep track of everything.
6 | - Some function are named in a way that the reader is sent totally in a wrong direction (i.e: GatherNodeFaces actually frees the bsp and
7 | rebuild the surfaces.
8 |
9 | CSG: Constructive Solid Geometry (Technique used in solid modeling. Constructive solid geometry allows a modeler to create a complex surface or object by using Boolean operators to combine objects.)
10 | http://www.flipcode.com/archives/Constructive_Solid_Geometry.shtml
11 |
12 | Good CSG Union stuff
13 | http://mattn.ninex.info/files/MAPFiles.pdf
14 |
15 | Laidlaw and Naylor (BSP based approach)
16 | Laidlaw paper: http://www.cs.brown.edu/research/vis/docs/pdf/Laidlaw-1986-CSG.pdf
17 |
18 | The CSG system relies on a faked OOP system with two objects "inside" in csg4.c and "ouside" in outside.c
19 |
20 | Face splitting against a plane is used all across the board and seems to be seems to be Sutherland-Hodgma inspired.
21 |
22 | QBSP :
23 | ======
24 |
25 |
26 | Summarized QBSP call tree :
27 | ===========================
28 |
29 | Quake1 MAP format contains entities. The world is described as an entity which is ALWAYS the first entity in the map file.
30 | The world entity can be recognized because it has the key/value: "classname" "worldspawn"
31 | If the first entity in the map file does not have the right classname (worldspawn): This is a faulty file.
32 |
33 | mbrush_t brush_t:
34 | - The map editor delivers volumes as a collection of plan (4 minimun for a Tetrahedron, no upper limit).
35 | - They are read from the MAP file as mbrush_t.
36 | - Plan are clipped against each other in order to generate facelet grouped in brush_t.
37 | surface_t: Volume formed by the facelet are processed further (discarding invisible facelet) and clipping volume against
38 | each other. In the end only a skin remains, made of surface_t, each containing faces.
39 |
40 | mbrush_t (set of plans)--> brush_t (Set of face_t) --> (surface_t)
41 |
42 | Important note: A Surface is not necessarly flat. It is the result of brush volume clipped against each other in order to keep only a visible skin.
43 | Depending on how brushes interact with each other, a surface with many more faces than the brush_t add.
44 |
45 | main() //qbsp.c
46 | {
47 | ProcessFile (sourcename, destname)
48 | {
49 | LoadMapFile
50 | {
51 | | LoadFile //Read text from HardDrive to RAM
52 | | while
53 | | ( ParseEntity () //Read all brushes in an entity. The Quake map in one entity made of thousands of brushes.
54 | | {
55 | | //Read mbrush_t, store result in mapbrushes and add brush to entity's mbrush linked list.
56 | | }
57 | | )
58 | |
59 | }
60 |
61 | //At this point we have the world entity as an entity_t mbrush
62 |
63 | BeginBSPFile
64 |
65 | CreateHulls
66 | {
67 | ProcessEntity (entnum)
68 | {
69 | //Entity is now a set of mbrush_t
70 |
71 | ent = &entities[entnum];
72 |
73 | // Intersect all plans in the mbrush_t, generate actual faces and group them in brush_t
74 | bs = Brush_LoadEntity (ent, hullnum);
75 |
76 | //Entity is now a set of brush_t
77 |
78 | // take the brush_ts and clip off all overlapping and contained faces,leaving a perfect skin of the model with no hidden faces
79 | brushset = bs;
80 | surfs = CSGFaces (bs)
81 |
82 | // A Surface is not necessarly flat. It is the result of brush volume clipped against each other in order to keep only
83 | // a visible skin.
84 |
85 | if (entnum == 0 && !nofill) // assume non-world bmodels are simple
86 | {
87 | PortalizeWorld (nodes);
88 | if (FillOutside (nodes))
89 | {
90 | | FreeAllPortals (nodes);
91 | |
92 | | // get the remaining faces together into surfaces again
93 | | surfs = GatherNodeFaces (nodes);
94 | |
95 | | // merge polygons
96 | | MergeAll (surfs);
97 | |
98 | | // make a really good tree
99 | | nodes = SolidBSP (surfs, false);
100 | |
101 | | // make the real portals for vis tracing
102 | | PortalizeWorld (nodes);
103 | |
104 | | // save portal file for vis tracing
105 | | WritePortalfile (nodes);
106 | |
107 | | // fix tjunctions
108 | | tjunc (nodes);
109 | }
110 | FreeAllPortals (nodes);
111 | }
112 |
113 | WriteNodePlanes (nodes);
114 | MakeFaceEdges (nodes);
115 |
116 | //Write the BSP Nodes.
117 | WriteDrawNodes (nodes);
118 | }
119 | }
120 | ReadClipHull (1)
121 | ReadClipHull (2)
122 |
123 | WriteEntitiesToString
124 | FinishBSPFile
125 | }
126 | }
127 |
128 |
129 | Unrolled QBSP :
130 | ===============
131 |
132 |
133 |
134 | Portal is generated from the optimized BSP tree (optimized mean that the spliting plan was chosen according to the least-split
135 | heurisitc instead of the mid-plan heuristic).
136 |
137 |
138 | Q & A :
139 | =======
140 |
141 | 1.BSP creation heuristic:
142 |
143 | Choose a surface, its plan is a candidate for becomming the splitting plan.
144 | Chose the plan that will generate the least cut.
145 |
146 | Subdivizion stops when no more surfaces are available.
147 | until all surfaces have been used. In the resulting final BSP leafs contain ONE surface
148 |
149 | When the BSP generator has no more surfaces, it looks at the content of the last splitted surface and set the leaf content.
150 |
151 | Testing proved all this wrong: By tracing I can see that some leafs contain 10 surfaces and 15 faces.....back to reading code:
152 |
153 |
154 | On split, any surface that is right on the splitting plane is marked via onnode and cannot be used as splitting plane later.
155 |
156 | A leaf can contains several surfaces if they are parallel ( the split selector will never chose a face that
157 | split no other polygon).
158 |
159 | 1. PartitionSurfaces recurse until a split plan is NOT returned. SelectPartition controls the recursion.
160 |
161 |
162 | 2. Why does a surface have several faces ?! A surface is supposed to be flat and can contain any number of vertices ?
163 |
164 | 3. What is the average number of portal per leafs ? Per node ?
165 | 4. How is the leaf content determinated ?
166 | 5. When does the BSP building process stops splitting ?
167 | 6. What ends up in the PRT file ?
168 | 7. How is the splitting node chosen ?
169 |
170 | PartitionSurfaces: At each recursion step the intial surface linked list can be changed. surface->next is EXTREMY likely
171 | to have been modified so using it, even for a leaf after the BSP has been built would be a non sense.
172 |
173 |
174 | Portals: It seems leak are an issue because the tool will not be able to determine which part is inside and which part is outside.
175 | Quake1 does not feature aeraportal (brush that modify the portal graph in realtime). https://developer.valvesoftware.com/wiki/Areaportal
176 | A nice explanation about aeraportal leaks (https://developer.valvesoftware.com/wiki/Areaportal). Explain that aeraportal
177 | can loop around itself.
178 |
179 | VIS :
180 | =====
181 |
182 |
183 |
184 |
185 |
186 | QCC :
187 | =====
188 |
189 | QuakeC Reference Manual
190 | http://pages.cs.wisc.edu/~jeremyp/quake/quakec/quakec.pdf
191 |
192 | Good tutorial:
193 |
194 | http://www.inside3d.com/showtutorial.php?id=153
195 | http://www.inside3d.com/showtutorial.php?id=154
196 | http://www.inside3d.com/showtutorial.php?id=156
197 | http://www.inside3d.com/showtutorial.php?id=157
198 |
199 |
200 | Looks like the compilation is the same as q3cc: The list of all the files to be compiled is in a file (here name progs.src).
201 |
202 | "progs.src" content :
203 | =====================
204 | ./qwprogs.dat
205 |
206 | defs.qc
207 | subs.qc
208 | combat.qc
209 | items.qc
210 | weapons.qc
211 | world.qc
212 | client.qc
213 | spectate.qc
214 | player.qc
215 | doors.qc
216 | buttons.qc
217 | triggers.qc
218 | plats.qc
219 | misc.qc
220 |
221 | server.qc
222 |
223 |
224 | Note: qwprogs.dat is the output filename.
--------------------------------------------------------------------------------
/qc/combat.qc:
--------------------------------------------------------------------------------
1 | /*
2 | combat.qc
3 |
4 | damage, obit, etc related functions
5 |
6 | Copyright (C) 1996-1997 Id Software, Inc.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 |
17 | See the GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to:
21 |
22 | Free Software Foundation, Inc.
23 | 59 Temple Place - Suite 330
24 | Boston, MA 02111-1307, USA
25 |
26 | */
27 |
28 | void() T_MissileTouch;
29 | void() info_player_start;
30 | void(entity targ, entity attacker) ClientObituary;
31 | void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage;
32 |
33 | /*SERVER
34 | void() monster_death_use;
35 | */
36 |
37 | //============================================================================
38 |
39 | /*
40 | ============
41 | CanDamage
42 |
43 | Returns true if the inflictor can directly damage the target. Used for
44 | explosions and melee attacks.
45 | ============
46 | */
47 | float(entity targ, entity inflictor) CanDamage =
48 | {
49 | // bmodels need special checking because their origin is 0,0,0
50 | if (targ.movetype == MOVETYPE_PUSH)
51 | {
52 | traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
53 | if (trace_fraction == 1)
54 | return TRUE;
55 | if (trace_ent == targ)
56 | return TRUE;
57 | return FALSE;
58 | }
59 |
60 | traceline(inflictor.origin, targ.origin, TRUE, self);
61 | if (trace_fraction == 1)
62 | return TRUE;
63 | traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
64 | if (trace_fraction == 1)
65 | return TRUE;
66 | traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
67 | if (trace_fraction == 1)
68 | return TRUE;
69 | traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
70 | if (trace_fraction == 1)
71 | return TRUE;
72 | traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
73 | if (trace_fraction == 1)
74 | return TRUE;
75 |
76 | return FALSE;
77 | };
78 |
79 |
80 | /*
81 | ============
82 | Killed
83 | ============
84 | */
85 | void(entity targ, entity attacker) Killed =
86 | {
87 | local entity oself;
88 |
89 | oself = self;
90 | self = targ;
91 |
92 | if (self.health < -99)
93 | self.health = -99; // don't let sbar look bad if a player
94 |
95 | if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
96 | { // doors, triggers, etc
97 | self.th_die ();
98 | self = oself;
99 | return;
100 | }
101 |
102 | self.enemy = attacker;
103 |
104 | // bump the monster counter
105 | if (self.flags & FL_MONSTER)
106 | {
107 | killed_monsters = killed_monsters + 1;
108 | WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
109 | }
110 |
111 | ClientObituary(self, attacker);
112 |
113 | self.takedamage = DAMAGE_NO;
114 | self.touch = SUB_Null;
115 | self.effects = 0;
116 |
117 | /*SERVER
118 | monster_death_use();
119 | */
120 | self.th_die ();
121 |
122 | self = oself;
123 | };
124 |
125 |
126 | /*
127 | ============
128 | T_Damage
129 |
130 | The damage is coming from inflictor, but get mad at attacker
131 | This should be the only function that ever reduces health.
132 | ============
133 | */
134 | void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
135 | {
136 | local vector dir;
137 | local entity oldself;
138 | local float save;
139 | local float take;
140 | local string s;
141 | local string attackerteam, targteam;
142 |
143 |
144 | if (!targ.takedamage)
145 | return;
146 |
147 | // used by buttons and triggers to set activator for target firing
148 | damage_attacker = attacker;
149 |
150 |
151 | // check for quad damage powerup on the attacker
152 | if (attacker.super_damage_finished > time && inflictor.classname != "door")
153 | if (deathmatch == 4)
154 | damage = damage * 8;
155 | else
156 | damage = damage * 4;
157 |
158 | // save damage based on the target's armor level
159 |
160 | save = ceil(targ.armortype*damage);
161 | if (save >= targ.armorvalue)
162 | {
163 | save = targ.armorvalue;
164 | targ.armortype = 0; // lost all armor
165 | targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
166 | }
167 |
168 | targ.armorvalue = targ.armorvalue - save;
169 | take = ceil(damage-save);
170 |
171 | // add to the damage total for clients, which will be sent as a single
172 | // message at the end of the frame
173 | // FIXME: remove after combining shotgun blasts?
174 | if (targ.flags & FL_CLIENT)
175 | {
176 | targ.dmg_take = targ.dmg_take + take;
177 | targ.dmg_save = targ.dmg_save + save;
178 | targ.dmg_inflictor = inflictor;
179 | }
180 |
181 | damage_inflictor = inflictor;
182 |
183 |
184 | // figure momentum add
185 | if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
186 | {
187 | dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
188 | dir = normalize(dir);
189 | // Set kickback for smaller weapons
190 | //Zoid -- use normal NQ kickback
191 | // // Read: only if it's not yourself doing the damage
192 | // if ( (damage < 60) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname != targ.netname))
193 | // targ.velocity = targ.velocity + dir * damage * 11;
194 | // else
195 | // Otherwise, these rules apply to rockets and grenades
196 | // for blast velocity
197 | targ.velocity = targ.velocity + dir * damage * 8;
198 |
199 | // Rocket Jump modifiers
200 | if ( (rj > 1) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname == targ.netname))
201 | targ.velocity = targ.velocity + dir * damage * rj;
202 |
203 | }
204 |
205 |
206 |
207 | // check for godmode or invincibility
208 | if (targ.flags & FL_GODMODE)
209 | return;
210 | if (targ.invincible_finished >= time)
211 | {
212 | if (self.invincible_sound < time)
213 | {
214 | sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
215 | self.invincible_sound = time + 2;
216 | }
217 | return;
218 | }
219 |
220 | // team play damage avoidance
221 | //ZOID 12-13-96: self.team doesn't work in QW. Use keys
222 | attackerteam = infokey(attacker, "team");
223 | targteam = infokey(targ, "team");
224 |
225 | if ((teamplay == 1) && (targteam == attackerteam) &&
226 | (attacker.classname == "player") && (attackerteam != "") &&
227 | inflictor.classname !="door")
228 | return;
229 |
230 | if ((teamplay == 3) && (targteam == attackerteam) &&
231 | (attacker.classname == "player") && (attackerteam != "") &&
232 | (targ != attacker)&& inflictor.classname !="door")
233 | return;
234 |
235 | // do the damage
236 | targ.health = targ.health - take;
237 |
238 | if (targ.health <= 0)
239 | {
240 | Killed (targ, attacker);
241 | return;
242 | }
243 |
244 | // react to the damage
245 | oldself = self;
246 | self = targ;
247 |
248 | /*SERVER
249 | if ( (self.flags & FL_MONSTER) && attacker != world)
250 | {
251 | // get mad unless of the same class (except for soldiers)
252 | if (self != attacker && attacker != self.enemy)
253 | {
254 | if ( (self.classname != attacker.classname)
255 | || (self.classname == "monster_army" ) )
256 | {
257 | if (self.enemy.classname == "player")
258 | self.oldenemy = self.enemy;
259 | self.enemy = attacker;
260 | FoundTarget ();
261 | }
262 | }
263 | }
264 | */
265 | if (self.th_pain)
266 | {
267 | self.th_pain (attacker, take);
268 | }
269 |
270 | self = oldself;
271 | };
272 |
273 | /*
274 | ============
275 | T_RadiusDamage
276 | ============
277 | */
278 | void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage =
279 | {
280 | local float points;
281 | local entity head;
282 | local vector org;
283 |
284 | head = findradius(inflictor.origin, damage+40);
285 |
286 | while (head)
287 | {
288 | //bprint (PRINT_HIGH, head.classname);
289 | //bprint (PRINT_HIGH, " | ");
290 | //bprint (PRINT_HIGH, head.netname);
291 | //bprint (PRINT_HIGH, "\n");
292 |
293 | if (head != ignore)
294 | {
295 | if (head.takedamage)
296 | {
297 | org = head.origin + (head.mins + head.maxs)*0.5;
298 | points = 0.5*vlen (inflictor.origin - org);
299 | if (points < 0)
300 | points = 0;
301 | points = damage - points;
302 |
303 | if (head == attacker)
304 | points = points * 0.5;
305 | if (points > 0)
306 | {
307 | if (CanDamage (head, inflictor))
308 | {
309 | head.deathtype = dtype;
310 | T_Damage (head, inflictor, attacker, points);
311 | }
312 | }
313 | }
314 | }
315 | head = head.chain;
316 | }
317 | };
318 |
319 | /*
320 | ============
321 | T_BeamDamage
322 | ============
323 | */
324 | void(entity attacker, float damage) T_BeamDamage =
325 | {
326 | local float points;
327 | local entity head;
328 |
329 | head = findradius(attacker.origin, damage+40);
330 |
331 | while (head)
332 | {
333 | if (head.takedamage)
334 | {
335 | points = 0.5*vlen (attacker.origin - head.origin);
336 | if (points < 0)
337 | points = 0;
338 | points = damage - points;
339 | if (head == attacker)
340 | points = points * 0.5;
341 | if (points > 0)
342 | {
343 | if (CanDamage (head, attacker))
344 | T_Damage (head, attacker, attacker, points);
345 | }
346 | }
347 | head = head.chain;
348 | }
349 | };
350 |
351 |
--------------------------------------------------------------------------------
/qbsp/bsp5.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | // bsp5.h
22 |
23 | #include "cmdlib.h"
24 | #include "mathlib.h"
25 | #include "bspfile.h"
26 |
27 | typedef struct
28 | {
29 | vec3_t normal;
30 | vec_t dist;
31 | int type;
32 | } plane_t;
33 |
34 |
35 | #include "map.h"
36 |
37 | #define MAX_THREADS 4
38 |
39 | #define ON_EPSILON 0.05
40 | #define BOGUS_RANGE 18000
41 |
42 | // the exact bounding box of the brushes is expanded some for the headnode
43 | // volume. is this still needed?
44 | #define SIDESPACE 24
45 |
46 | //============================================================================
47 |
48 |
49 | typedef struct
50 | {
51 | int numpoints;
52 | vec3_t points[8]; // variable sized
53 | } winding_t;
54 |
55 | #define MAX_POINTS_ON_WINDING 64
56 |
57 | winding_t *BaseWindingForPlane (plane_t *p);
58 | void CheckWinding (winding_t *w);
59 | winding_t *NewWinding (int points);
60 | void FreeWinding (winding_t *w);
61 | winding_t *CopyWinding (winding_t *w);
62 | winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon);
63 | void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t **back);
64 |
65 | //============================================================================
66 |
67 | #define MAXEDGES 32
68 | #define MAXPOINTS 28 // don't let a base face get past this
69 | // because it can be split more later
70 |
71 | typedef struct visfacet_s
72 | {
73 | struct visfacet_s *next;
74 |
75 | int planenum;
76 | int planeside; // which side is the front of the face
77 | int texturenum;
78 | int contents[2]; // 0 = front side
79 |
80 | struct visfacet_s *original; // face on node
81 | int outputnumber; // only valid for original faces after
82 | // write surfaces
83 | int numpoints;
84 | vec3_t pts[MAXEDGES]; // FIXME: change to use winding_t
85 | int edges[MAXEDGES];
86 | } face_t;
87 |
88 |
89 | typedef struct surface_s
90 | {
91 | struct surface_s *next;
92 | struct surface_s *original; // before BSP cuts it up
93 |
94 | int planenum; // FCS: planenum is a reference to a plane_t in
95 |
96 | int outputplanenum; // only valid after WriteSurfacePlanes
97 | vec3_t mins, maxs;
98 | qboolean onnode; // true if surface has already been used
99 | // as a splitting node
100 | face_t *faces; // links to all the faces on either side of the surf
101 | } surface_t;
102 |
103 |
104 | //
105 | // there is a node_t structure for every node and leaf in the bsp tree
106 | //
107 | #define PLANENUM_LEAF -1
108 |
109 | typedef struct node_s
110 | {
111 | vec3_t mins,maxs; // bounding volume, not just points inside
112 |
113 | // information for decision nodes
114 | int planenum; // -1 = leaf node
115 | int outputplanenum; // only valid after WriteNodePlanes
116 | int firstface; // decision node only
117 | int numfaces; // decision node only
118 | struct node_s *children[2]; // only valid for decision nodes
119 | face_t *faces; // decision nodes only, list for both sides
120 |
121 | // information for leafs
122 | int contents; // leaf nodes (0 for decision nodes)
123 | face_t **markfaces; // leaf nodes only, point to node faces //FCS: Original faces
124 | struct portal_s *portals;
125 | int visleafnum; // -1 = solid
126 | int valid; // for flood filling
127 | int occupied; // light number in leaf for outside filling
128 | } node_t;
129 |
130 | //=============================================================================
131 |
132 | // brush.c
133 |
134 | #define NUM_HULLS 2 // normal and +16
135 |
136 | #define NUM_CONTENTS 2 // solid and water
137 |
138 | typedef struct brush_s
139 | {
140 | struct brush_s *next;
141 | vec3_t mins, maxs;
142 | face_t *faces;
143 | int contents;
144 | } brush_t;
145 |
146 | typedef struct
147 | {
148 | vec3_t mins, maxs;
149 | brush_t *brushes; // NULL terminated list
150 | } brushset_t;
151 |
152 | extern int numbrushplanes;
153 | extern plane_t planes[MAX_MAP_PLANES];
154 |
155 | brushset_t *Brush_LoadEntity (entity_t *ent, int hullnum);
156 | int PlaneTypeForNormal (vec3_t normal);
157 | int FindPlane (plane_t *dplane, int *side);
158 |
159 | //=============================================================================
160 |
161 | // csg4.c
162 |
163 | // build surfaces is also used by GatherNodeFaces
164 | extern face_t *validfaces[MAX_MAP_PLANES];
165 | surface_t *BuildSurfaces (void);
166 |
167 | face_t *NewFaceFromFace (face_t *in);
168 | surface_t *CSGFaces (brushset_t *bs);
169 | void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back);
170 |
171 | //=============================================================================
172 |
173 | // solidbsp.c
174 |
175 | void DivideFacet (face_t *in, plane_t *split, face_t **front, face_t **back);
176 | void CalcSurfaceInfo (surface_t *surf);
177 | void SubdivideFace (face_t *f, face_t **prevptr);
178 | node_t *SolidBSP (surface_t *surfhead, qboolean midsplit);
179 |
180 | //=============================================================================
181 |
182 | // merge.c
183 |
184 | void MergePlaneFaces (surface_t *plane);
185 | face_t *MergeFaceToList (face_t *face, face_t *list);
186 | face_t *FreeMergeListScraps (face_t *merged);
187 | void MergeAll (surface_t *surfhead);
188 |
189 | //=============================================================================
190 |
191 | // surfaces.c
192 |
193 | extern int c_cornerverts;
194 | extern int c_tryedges;
195 | extern face_t *edgefaces[MAX_MAP_EDGES][2];
196 |
197 | extern int firstmodeledge;
198 | extern int firstmodelface;
199 |
200 | void SubdivideFaces (surface_t *surfhead);
201 |
202 | surface_t *GatherNodeFaces (node_t *headnode);
203 |
204 | void MakeFaceEdges (node_t *headnode);
205 |
206 | //=============================================================================
207 |
208 | // portals.c
209 |
210 | typedef struct portal_s
211 | {
212 | int planenum;
213 | node_t *nodes[2]; // [0] = front side of planenum
214 | struct portal_s *next[2];
215 | winding_t *winding;
216 | } portal_t;
217 |
218 | extern node_t outside_node; // portals outside the world face this
219 |
220 | void PortalizeWorld (node_t *headnode);
221 | void WritePortalfile (node_t *headnode);
222 | void FreeAllPortals (node_t *node);
223 |
224 | //=============================================================================
225 |
226 | // region.c
227 |
228 | void GrowNodeRegions (node_t *headnode);
229 |
230 | //=============================================================================
231 |
232 | // tjunc.c
233 |
234 | void tjunc (node_t *headnode);
235 |
236 | //=============================================================================
237 |
238 | // writebsp.c
239 |
240 | void WriteNodePlanes (node_t *headnode);
241 | void WriteClipNodes (node_t *headnode);
242 | void WriteDrawNodes (node_t *headnode);
243 |
244 | void BumpModel (int hullnum);
245 | int FindFinalPlane (dplane_t *p);
246 |
247 | void BeginBSPFile (void);
248 | void FinishBSPFile (void);
249 |
250 | //=============================================================================
251 |
252 | // draw.c
253 |
254 | void Draw_ClearBounds (void);
255 | void Draw_AddToBounds (vec3_t v);
256 | void Draw_DrawFace (face_t *f);
257 | void Draw_ClearWindow (void);
258 | void Draw_SetRed (void);
259 | void Draw_SetGrey (void);
260 | void Draw_SetBlack (void);
261 | void DrawPoint (vec3_t v);
262 |
263 | void Draw_SetColor (int c);
264 | void SetColor (int c);
265 | void DrawPortal (portal_t *p);
266 | void DrawLeaf (node_t *l, int color);
267 | void DrawBrush (brush_t *b);
268 |
269 | void DrawWinding (winding_t *w);
270 | void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3);
271 |
272 | //=============================================================================
273 |
274 | // outside.c
275 |
276 | qboolean FillOutside (node_t *node);
277 |
278 | //=============================================================================
279 |
280 | extern qboolean drawflag;
281 | extern qboolean nofill;
282 | extern qboolean notjunc;
283 | extern qboolean noclip;
284 | extern qboolean verbose;
285 |
286 | extern int subdivide_size;
287 |
288 | extern int hullnum;
289 |
290 | extern brushset_t *brushset;
291 |
292 | void qprintf (char *fmt, ...); // only prints if verbose
293 |
294 | extern int valid;
295 |
296 | extern char portfilename[1024];
297 | extern char bspfilename[1024];
298 | extern char pointfilename[1024];
299 |
300 | extern qboolean worldmodel;
301 |
302 |
303 | // misc functions
304 |
305 | face_t *AllocFace (void);
306 | void FreeFace (face_t *f);
307 |
308 | struct portal_s *AllocPortal (void);
309 | void FreePortal (struct portal_s *p);
310 |
311 | surface_t *AllocSurface (void);
312 | void FreeSurface (surface_t *s);
313 |
314 | node_t *AllocNode (void);
315 | struct brush_s *AllocBrush (void);
316 |
317 | //=============================================================================
318 |
319 |
--------------------------------------------------------------------------------
/common/polylib.c:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 1996-1997 Id Software, Inc.
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 |
17 | See file, 'COPYING', for details.
18 | */
19 |
20 |
21 | #include "cmdlib.h"
22 | #include "mathlib.h"
23 | #include "polylib.h"
24 |
25 | #define BOGUS_RANGE 8192
26 |
27 | /*
28 | =============
29 | AllocWinding
30 | =============
31 | */
32 | winding_t *AllocWinding (int points)
33 | {
34 | winding_t *w;
35 | int s;
36 |
37 | s = sizeof(vec_t)*3*points + sizeof(int);
38 | w = malloc (s);
39 | memset (w, 0, s);
40 | return w;
41 | }
42 |
43 | /*
44 | ============
45 | RemoveColinearPoints
46 | ============
47 | */
48 | int c_removed;
49 |
50 | void RemoveColinearPoints (winding_t *w)
51 | {
52 | int i, j, k;
53 | vec3_t v1, v2;
54 | int nump;
55 | vec3_t p[MAX_POINTS_ON_WINDING];
56 |
57 | nump = 0;
58 | for (i=0 ; inumpoints ; i++)
59 | {
60 | j = (i+1)%w->numpoints;
61 | k = (i+w->numpoints-1)%w->numpoints;
62 | VectorSubtract (w->p[j], w->p[i], v1);
63 | VectorSubtract (w->p[i], w->p[k], v2);
64 | VectorNormalize(v1);
65 | VectorNormalize(v2);
66 | if (DotProduct(v1, v2) < 0.999)
67 | {
68 | VectorCopy (w->p[i], p[nump]);
69 | nump++;
70 | }
71 | }
72 |
73 | if (nump == w->numpoints)
74 | return;
75 |
76 | c_removed += w->numpoints - nump;
77 | w->numpoints = nump;
78 | memcpy (w->p, p, nump*sizeof(p[0]));
79 | }
80 |
81 | /*
82 | ============
83 | WindingPlane
84 | ============
85 | */
86 | void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist)
87 | {
88 | vec3_t v1, v2;
89 |
90 | VectorSubtract (w->p[1], w->p[0], v1);
91 | VectorSubtract (w->p[2], w->p[0], v2);
92 | CrossProduct (v1, v2, normal);
93 | VectorNormalize (normal);
94 | *dist = DotProduct (w->p[0], normal);
95 |
96 | }
97 |
98 | /*
99 | =============
100 | WindingArea
101 | =============
102 | */
103 | vec_t WindingArea (winding_t *w)
104 | {
105 | int i;
106 | vec3_t d1, d2, cross;
107 | vec_t total;
108 |
109 | total = 0;
110 | for (i=2 ; inumpoints ; i++)
111 | {
112 | VectorSubtract (w->p[i-1], w->p[0], d1);
113 | VectorSubtract (w->p[i], w->p[0], d2);
114 | CrossProduct (d1, d2, cross);
115 | total += 0.5 * VectorLength ( cross );
116 | }
117 | return total;
118 | }
119 |
120 | /*
121 | =============
122 | WindingCenter
123 | =============
124 | */
125 | void WindingCenter (winding_t *w, vec3_t center)
126 | {
127 | int i;
128 | vec3_t d1, d2, cross;
129 | float scale;
130 |
131 | VectorCopy (vec3_origin, center);
132 | for (i=0 ; inumpoints ; i++)
133 | VectorAdd (w->p[i], center, center);
134 |
135 | scale = 1.0/w->numpoints;
136 | VectorScale (center, scale, center);
137 | }
138 |
139 | /*
140 | =================
141 | BaseWindingForPlane
142 | =================
143 | */
144 | winding_t *BaseWindingForPlane (vec3_t normal, float dist)
145 | {
146 | int i, x;
147 | vec_t max, v;
148 | vec3_t org, vright, vup;
149 | winding_t *w;
150 |
151 | // find the major axis
152 |
153 | max = -BOGUS_RANGE;
154 | x = -1;
155 | for (i=0 ; i<3; i++)
156 | {
157 | v = fabs(normal[i]);
158 | if (v > max)
159 | {
160 | x = i;
161 | max = v;
162 | }
163 | }
164 | if (x==-1)
165 | Error ("BaseWindingForPlane: no axis found");
166 |
167 | VectorCopy (vec3_origin, vup);
168 | switch (x)
169 | {
170 | case 0:
171 | case 1:
172 | vup[2] = 1;
173 | break;
174 | case 2:
175 | vup[0] = 1;
176 | break;
177 | }
178 |
179 | v = DotProduct (vup, normal);
180 | VectorMA (vup, -v, normal, vup);
181 | VectorNormalize (vup);
182 |
183 | VectorScale (normal, dist, org);
184 |
185 | CrossProduct (vup, normal, vright);
186 |
187 | VectorScale (vup, 8192, vup);
188 | VectorScale (vright, 8192, vright);
189 |
190 | // project a really big axis aligned box onto the plane
191 | w = AllocWinding (4);
192 |
193 | VectorSubtract (org, vright, w->p[0]);
194 | VectorAdd (w->p[0], vup, w->p[0]);
195 |
196 | VectorAdd (org, vright, w->p[1]);
197 | VectorAdd (w->p[1], vup, w->p[1]);
198 |
199 | VectorAdd (org, vright, w->p[2]);
200 | VectorSubtract (w->p[2], vup, w->p[2]);
201 |
202 | VectorSubtract (org, vright, w->p[3]);
203 | VectorSubtract (w->p[3], vup, w->p[3]);
204 |
205 | w->numpoints = 4;
206 |
207 | return w;
208 | }
209 |
210 | /*
211 | ==================
212 | CopyWinding
213 | ==================
214 | */
215 | winding_t *CopyWinding (winding_t *w)
216 | {
217 | int size;
218 | winding_t *c;
219 |
220 | size = (int)((winding_t *)0)->p[w->numpoints];
221 | c = malloc (size);
222 | memcpy (c, w, size);
223 | return c;
224 | }
225 |
226 |
227 | /*
228 | =============
229 | ClipWinding
230 | =============
231 | */
232 | void ClipWinding (winding_t *in, vec3_t normal, vec_t dist,
233 | winding_t **front, winding_t **back)
234 | {
235 | vec_t dists[MAX_POINTS_ON_WINDING+4];
236 | int sides[MAX_POINTS_ON_WINDING+4];
237 | int counts[3];
238 | vec_t dot;
239 | int i, j;
240 | vec_t *p1, *p2;
241 | vec3_t mid;
242 | winding_t *f, *b;
243 | int maxpts;
244 |
245 | counts[0] = counts[1] = counts[2] = 0;
246 |
247 | // determine sides for each point
248 | for (i=0 ; inumpoints ; i++)
249 | {
250 | dot = DotProduct (in->p[i], normal);
251 | dot -= dist;
252 | dists[i] = dot;
253 | if (dot > ON_EPSILON)
254 | sides[i] = SIDE_FRONT;
255 | else if (dot < -ON_EPSILON)
256 | sides[i] = SIDE_BACK;
257 | else
258 | {
259 | sides[i] = SIDE_ON;
260 | }
261 | counts[sides[i]]++;
262 | }
263 | sides[i] = sides[0];
264 | dists[i] = dists[0];
265 |
266 | *front = *back = NULL;
267 |
268 | if (!counts[0])
269 | {
270 | *back = CopyWinding (in);
271 | return;
272 | }
273 | if (!counts[1])
274 | {
275 | *front = CopyWinding (in);
276 | return;
277 | }
278 |
279 | maxpts = in->numpoints+4; // can't use counts[0]+2 because
280 | // of fp grouping errors
281 |
282 | *front = f = AllocWinding (maxpts);
283 | *back = b = AllocWinding (maxpts);
284 |
285 | for (i=0 ; inumpoints ; i++)
286 | {
287 | p1 = in->p[i];
288 |
289 | if (sides[i] == SIDE_ON)
290 | {
291 | VectorCopy (p1, f->p[f->numpoints]);
292 | f->numpoints++;
293 | VectorCopy (p1, b->p[b->numpoints]);
294 | b->numpoints++;
295 | continue;
296 | }
297 |
298 | if (sides[i] == SIDE_FRONT)
299 | {
300 | VectorCopy (p1, f->p[f->numpoints]);
301 | f->numpoints++;
302 | }
303 | if (sides[i] == SIDE_BACK)
304 | {
305 | VectorCopy (p1, b->p[b->numpoints]);
306 | b->numpoints++;
307 | }
308 |
309 | if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
310 | continue;
311 |
312 | // generate a split point
313 | p2 = in->p[(i+1)%in->numpoints];
314 |
315 | dot = dists[i] / (dists[i]-dists[i+1]);
316 | for (j=0 ; j<3 ; j++)
317 | { // avoid round off error when possible
318 | if (normal[j] == 1)
319 | mid[j] = dist;
320 | else if (normal[j] == -1)
321 | mid[j] = -dist;
322 | else
323 | mid[j] = p1[j] + dot*(p2[j]-p1[j]);
324 | }
325 |
326 | VectorCopy (mid, f->p[f->numpoints]);
327 | f->numpoints++;
328 | VectorCopy (mid, b->p[b->numpoints]);
329 | b->numpoints++;
330 | }
331 |
332 | if (f->numpoints > maxpts || b->numpoints > maxpts)
333 | Error ("ClipWinding: points exceeded estimate");
334 | if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
335 | Error ("ClipWinding: MAX_POINTS_ON_WINDING");
336 | }
337 |
338 | /*
339 | =================
340 | ChopWinding
341 |
342 | Returns the fragment of in that is on the front side
343 | of the cliping plane. The original is freed.
344 | =================
345 | */
346 | winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist)
347 | {
348 | winding_t *f, *b;
349 |
350 | ClipWinding (in, normal, dist, &f, &b);
351 | free (in);
352 | if (b)
353 | free (b);
354 | return f;
355 | }
356 |
357 | /*
358 | =================
359 | CheckWinding
360 |
361 | =================
362 | */
363 | void CheckWinding (winding_t *w)
364 | {
365 | int i, j;
366 | vec_t *p1, *p2;
367 | vec_t d, edgedist;
368 | vec3_t dir, edgenormal, facenormal;
369 | vec_t area;
370 | vec_t facedist;
371 |
372 | if (w->numpoints < 3)
373 | Error ("CheckFace: %i points",w->numpoints);
374 |
375 | area = WindingArea(w);
376 | if (area < 1)
377 | Error ("CheckFace: %f area", area);
378 |
379 | WindingPlane (w, facenormal, &facedist);
380 |
381 | for (i=0 ; inumpoints ; i++)
382 | {
383 | p1 = w->p[i];
384 |
385 | for (j=0 ; j<3 ; j++)
386 | if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
387 | Error ("CheckFace: BUGUS_RANGE: %f",p1[j]);
388 |
389 | j = i+1 == w->numpoints ? 0 : i+1;
390 |
391 | // check the point is on the face plane
392 | d = DotProduct (p1, facenormal) - facedist;
393 | if (d < -ON_EPSILON || d > ON_EPSILON)
394 | Error ("CheckFace: point off plane");
395 |
396 | // check the edge isn't degenerate
397 | p2 = w->p[j];
398 | VectorSubtract (p2, p1, dir);
399 |
400 | if (VectorLength (dir) < ON_EPSILON)
401 | Error ("CheckFace: degenerate edge");
402 |
403 | CrossProduct (facenormal, dir, edgenormal);
404 | VectorNormalize (edgenormal);
405 | edgedist = DotProduct (p1, edgenormal);
406 | edgedist += ON_EPSILON;
407 |
408 | // all other points must be on front side
409 | for (j=0 ; jnumpoints ; j++)
410 | {
411 | if (j == i)
412 | continue;
413 | d = DotProduct (w->p[j], edgenormal);
414 | if (d > edgedist)
415 | Error ("CheckFace: non-convex");
416 | }
417 | }
418 | }
419 |
420 |
--------------------------------------------------------------------------------
/qc/plats.qc:
--------------------------------------------------------------------------------
1 | /*
2 | plats.qc
3 |
4 | platform functions
5 |
6 | Copyright (C) 1996-1997 Id Software, Inc.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 |
17 | See the GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to:
21 |
22 | Free Software Foundation, Inc.
23 | 59 Temple Place - Suite 330
24 | Boston, MA 02111-1307, USA
25 |
26 | */
27 |
28 |
29 | void() plat_center_touch;
30 | void() plat_outside_touch;
31 | void() plat_trigger_use;
32 | void() plat_go_up;
33 | void() plat_go_down;
34 | void() plat_crush;
35 | float PLAT_LOW_TRIGGER = 1;
36 |
37 | void() plat_spawn_inside_trigger =
38 | {
39 | local entity trigger;
40 | local vector tmin, tmax;
41 |
42 | //
43 | // middle trigger
44 | //
45 | trigger = spawn();
46 | trigger.touch = plat_center_touch;
47 | trigger.movetype = MOVETYPE_NONE;
48 | trigger.solid = SOLID_TRIGGER;
49 | trigger.enemy = self;
50 |
51 | tmin = self.mins + '25 25 0';
52 | tmax = self.maxs - '25 25 -8';
53 | tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
54 | if (self.spawnflags & PLAT_LOW_TRIGGER)
55 | tmax_z = tmin_z + 8;
56 |
57 | if (self.size_x <= 50)
58 | {
59 | tmin_x = (self.mins_x + self.maxs_x) / 2;
60 | tmax_x = tmin_x + 1;
61 | }
62 | if (self.size_y <= 50)
63 | {
64 | tmin_y = (self.mins_y + self.maxs_y) / 2;
65 | tmax_y = tmin_y + 1;
66 | }
67 |
68 | setsize (trigger, tmin, tmax);
69 | };
70 |
71 | void() plat_hit_top =
72 | {
73 | sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
74 | self.state = STATE_TOP;
75 | self.think = plat_go_down;
76 | self.nextthink = self.ltime + 3;
77 | };
78 |
79 | void() plat_hit_bottom =
80 | {
81 | sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM);
82 | self.state = STATE_BOTTOM;
83 | };
84 |
85 | void() plat_go_down =
86 | {
87 | sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
88 | self.state = STATE_DOWN;
89 | SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
90 | };
91 |
92 | void() plat_go_up =
93 | {
94 | sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
95 | self.state = STATE_UP;
96 | SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
97 | };
98 |
99 | void() plat_center_touch =
100 | {
101 | if (other.classname != "player")
102 | return;
103 |
104 | if (other.health <= 0)
105 | return;
106 |
107 | self = self.enemy;
108 | if (self.state == STATE_BOTTOM)
109 | plat_go_up ();
110 | else if (self.state == STATE_TOP)
111 | self.nextthink = self.ltime + 1; // delay going down
112 | };
113 |
114 | void() plat_outside_touch =
115 | {
116 | if (other.classname != "player")
117 | return;
118 |
119 | if (other.health <= 0)
120 | return;
121 |
122 | //dprint ("plat_outside_touch\n");
123 | self = self.enemy;
124 | if (self.state == STATE_TOP)
125 | plat_go_down ();
126 | };
127 |
128 | void() plat_trigger_use =
129 | {
130 | if (self.think)
131 | return; // allready activated
132 | plat_go_down();
133 | };
134 |
135 |
136 | void() plat_crush =
137 | {
138 | //dprint ("plat_crush\n");
139 |
140 | other.deathtype = "squish";
141 | T_Damage (other, self, self, 1);
142 |
143 | if (self.state == STATE_UP)
144 | plat_go_down ();
145 | else if (self.state == STATE_DOWN)
146 | plat_go_up ();
147 | else
148 | objerror ("plat_crush: bad self.state\n");
149 | };
150 |
151 | void() plat_use =
152 | {
153 | self.use = SUB_Null;
154 | if (self.state != STATE_UP)
155 | objerror ("plat_use: not in up state");
156 | plat_go_down();
157 | };
158 |
159 |
160 | /*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER
161 | speed default 150
162 |
163 | Plats are always drawn in the extended position, so they will light correctly.
164 |
165 | If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
166 |
167 | If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
168 | Set "sounds" to one of the following:
169 | 1) base fast
170 | 2) chain slow
171 | */
172 |
173 |
174 | void() func_plat =
175 |
176 | {
177 | local entity t;
178 |
179 | if (!self.t_length)
180 | self.t_length = 80;
181 | if (!self.t_width)
182 | self.t_width = 10;
183 |
184 | if (self.sounds == 0)
185 | self.sounds = 2;
186 | // FIX THIS TO LOAD A GENERIC PLAT SOUND
187 |
188 | if (self.sounds == 1)
189 | {
190 | precache_sound ("plats/plat1.wav");
191 | precache_sound ("plats/plat2.wav");
192 | self.noise = "plats/plat1.wav";
193 | self.noise1 = "plats/plat2.wav";
194 | }
195 |
196 | if (self.sounds == 2)
197 | {
198 | precache_sound ("plats/medplat1.wav");
199 | precache_sound ("plats/medplat2.wav");
200 | self.noise = "plats/medplat1.wav";
201 | self.noise1 = "plats/medplat2.wav";
202 | }
203 |
204 |
205 | self.mangle = self.angles;
206 | self.angles = '0 0 0';
207 |
208 | self.classname = "plat";
209 | self.solid = SOLID_BSP;
210 | self.movetype = MOVETYPE_PUSH;
211 | setorigin (self, self.origin);
212 | setmodel (self, self.model);
213 | setsize (self, self.mins , self.maxs);
214 |
215 | self.blocked = plat_crush;
216 | if (!self.speed)
217 | self.speed = 150;
218 |
219 | // pos1 is the top position, pos2 is the bottom
220 | self.pos1 = self.origin;
221 | self.pos2 = self.origin;
222 | if (self.height)
223 | self.pos2_z = self.origin_z - self.height;
224 | else
225 | self.pos2_z = self.origin_z - self.size_z + 8;
226 |
227 | self.use = plat_trigger_use;
228 |
229 | plat_spawn_inside_trigger (); // the "start moving" trigger
230 |
231 | if (self.targetname)
232 | {
233 | self.state = STATE_UP;
234 | self.use = plat_use;
235 | }
236 | else
237 | {
238 | setorigin (self, self.pos2);
239 | self.state = STATE_BOTTOM;
240 | }
241 | };
242 |
243 | //============================================================================
244 |
245 | void() train_next;
246 | void() func_train_find;
247 |
248 | void() train_blocked =
249 | {
250 | if (time < self.attack_finished)
251 | return;
252 | self.attack_finished = time + 0.5;
253 | other.deathtype = "squish";
254 | T_Damage (other, self, self, self.dmg);
255 | };
256 |
257 | void() train_use =
258 | {
259 | if (self.think != func_train_find)
260 | return; // already activated
261 | train_next();
262 | };
263 |
264 | void() train_wait =
265 | {
266 | if (self.wait)
267 | {
268 | self.nextthink = self.ltime + self.wait;
269 | sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise, 1, ATTN_NORM);
270 | }
271 | else
272 | self.nextthink = self.ltime + 0.1;
273 |
274 | self.think = train_next;
275 | };
276 |
277 | void() train_next =
278 | {
279 | local entity targ;
280 |
281 | targ = find (world, targetname, self.target);
282 | self.target = targ.target;
283 | if (!self.target)
284 | objerror ("train_next: no next target");
285 | if (targ.wait)
286 | self.wait = targ.wait;
287 | else
288 | self.wait = 0;
289 | sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
290 | SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait);
291 | };
292 |
293 | void() func_train_find =
294 |
295 | {
296 | local entity targ;
297 |
298 | targ = find (world, targetname, self.target);
299 | self.target = targ.target;
300 | setorigin (self, targ.origin - self.mins);
301 | if (!self.targetname)
302 | { // not triggered, so start immediately
303 | self.nextthink = self.ltime + 0.1;
304 | self.think = train_next;
305 | }
306 | };
307 |
308 | /*QUAKED func_train (0 .5 .8) ?
309 | Trains are moving platforms that players can ride.
310 | The targets origin specifies the min point of the train at each corner.
311 | The train spawns at the first target it is pointing at.
312 | If the train is the target of a button or trigger, it will not begin moving until activated.
313 | speed default 100
314 | dmg default 2
315 | sounds
316 | 1) ratchet metal
317 |
318 | */
319 | void() func_train =
320 | {
321 | if (!self.speed)
322 | self.speed = 100;
323 | if (!self.target)
324 | objerror ("func_train without a target");
325 | if (!self.dmg)
326 | self.dmg = 2;
327 |
328 | if (self.sounds == 0)
329 | {
330 | self.noise = ("misc/null.wav");
331 | precache_sound ("misc/null.wav");
332 | self.noise1 = ("misc/null.wav");
333 | precache_sound ("misc/null.wav");
334 | }
335 |
336 | if (self.sounds == 1)
337 | {
338 | self.noise = ("plats/train2.wav");
339 | precache_sound ("plats/train2.wav");
340 | self.noise1 = ("plats/train1.wav");
341 | precache_sound ("plats/train1.wav");
342 | }
343 |
344 | self.cnt = 1;
345 | self.solid = SOLID_BSP;
346 | self.movetype = MOVETYPE_PUSH;
347 | self.blocked = train_blocked;
348 | self.use = train_use;
349 | self.classname = "train";
350 |
351 | setmodel (self, self.model);
352 | setsize (self, self.mins , self.maxs);
353 | setorigin (self, self.origin);
354 |
355 | // start trains on the second frame, to make sure their targets have had
356 | // a chance to spawn
357 | self.nextthink = self.ltime + 0.1;
358 | self.think = func_train_find;
359 | };
360 |
361 | /*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8)
362 | This is used for the final bos
363 | */
364 | void() misc_teleporttrain =
365 | {
366 | if (!self.speed)
367 | self.speed = 100;
368 | if (!self.target)
369 | objerror ("func_train without a target");
370 |
371 | self.cnt = 1;
372 | self.solid = SOLID_NOT;
373 | self.movetype = MOVETYPE_PUSH;
374 | self.blocked = train_blocked;
375 | self.use = train_use;
376 | self.avelocity = '100 200 300';
377 |
378 | self.noise = ("misc/null.wav");
379 | precache_sound ("misc/null.wav");
380 | self.noise1 = ("misc/null.wav");
381 | precache_sound ("misc/null.wav");
382 |
383 | precache_model2 ("progs/teleport.mdl");
384 | setmodel (self, "progs/teleport.mdl");
385 | setsize (self, self.mins , self.maxs);
386 | setorigin (self, self.origin);
387 |
388 | // start trains on the second frame, to make sure their targets have had
389 | // a chance to spawn
390 | self.nextthink = self.ltime + 0.1;
391 | self.think = func_train_find;
392 | };
393 |
394 |
--------------------------------------------------------------------------------