1 /*
2 **	r_3dfloors.cpp
3 **	software 3D floors addon
4 **
5 **	by kgsws
6 */
7 
8 #include "templates.h"
9 #include "doomdef.h"
10 #include "p_local.h"
11 #include "c_dispatch.h"
12 #include "r_local.h"
13 #include "r_bsp.h"
14 #include "r_plane.h"
15 #include "c_cvars.h"
16 #include "r_3dfloors.h"
17 
18 // external variables
19 int fake3D;
20 F3DFloor *fakeFloor;
21 fixed_t fakeHeight;
22 fixed_t fakeAlpha;
23 int fakeActive = 0;
24 fixed_t sclipBottom;
25 fixed_t sclipTop;
26 HeightLevel *height_top = NULL;
27 HeightLevel *height_cur = NULL;
28 int CurrentMirror = 0;
29 int CurrentSkybox = 0;
30 
31 CVAR(Int, r_3dfloors, true, 0);
32 
33 // private variables
34 int height_max = -1;
35 TArray<HeightStack> toplist;
36 ClipStack *clip_top = NULL;
37 ClipStack *clip_cur = NULL;
38 
R_3D_DeleteHeights()39 void R_3D_DeleteHeights()
40 {
41 	height_cur = height_top;
42 	while(height_cur) {
43 		height_top = height_cur;
44 		height_cur = height_cur->next;
45 		M_Free(height_top);
46 	}
47 	height_max = -1;
48 	height_top = height_cur = NULL;
49 }
50 
R_3D_AddHeight(secplane_t * add,sector_t * sec)51 void R_3D_AddHeight(secplane_t *add, sector_t *sec)
52 {
53 	HeightLevel *near;
54 	HeightLevel *curr;
55 	fixed_t height;
56 
57 	height = add->ZatPoint(viewx, viewy);
58 	if(height >= sec->CenterCeiling()) return;
59 	if(height <= sec->CenterFloor()) return;
60 
61 	fakeActive = 1;
62 
63 	if(height_max >= 0) {
64 		near = height_top;
65 		while(near && near->height < height) near = near->next;
66 		if(near) {
67 			if(near->height == height) return;
68 			curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
69 			curr->height = height;
70 			curr->prev = near->prev;
71 			curr->next = near;
72 			if(near->prev) near->prev->next = curr;
73 			else height_top = curr;
74 			near->prev = curr;
75 		} else {
76 			curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
77 			curr->height = height;
78 			curr->prev = height_cur;
79 			curr->next = NULL;
80 			height_cur->next = curr;
81 			height_cur = curr;
82 		}
83 	} else {
84 		height_top = height_cur = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
85 		height_top->height = height;
86 		height_top->prev = NULL;
87 		height_top->next = NULL;
88 	}
89 	height_max++;
90 }
91 
R_3D_NewClip()92 void R_3D_NewClip()
93 {
94 	ClipStack *curr;
95 //	extern short floorclip[MAXWIDTH];
96 //	extern short ceilingclip[MAXWIDTH];
97 
98 	curr = (ClipStack*)M_Malloc(sizeof(ClipStack));
99 	curr->next = 0;
100 	memcpy(curr->floorclip, floorclip, sizeof(short) * MAXWIDTH);
101 	memcpy(curr->ceilingclip, ceilingclip, sizeof(short) * MAXWIDTH);
102 	curr->ffloor = fakeFloor;
103 	assert(fakeFloor->floorclip == NULL);
104 	assert(fakeFloor->ceilingclip == NULL);
105 	fakeFloor->floorclip = curr->floorclip;
106 	fakeFloor->ceilingclip = curr->ceilingclip;
107 	if(clip_top) {
108 		clip_cur->next = curr;
109 		clip_cur = curr;
110 	} else {
111 		clip_top = clip_cur = curr;
112 	}
113 }
114 
R_3D_ResetClip()115 void R_3D_ResetClip()
116 {
117 	clip_cur = clip_top;
118 	while(clip_cur)
119 	{
120 		assert(clip_cur->ffloor->floorclip != NULL);
121 		assert(clip_cur->ffloor->ceilingclip != NULL);
122 		clip_cur->ffloor->ceilingclip = clip_cur->ffloor->floorclip = NULL;
123 		clip_top = clip_cur;
124 		clip_cur = clip_cur->next;
125 		M_Free(clip_top);
126 	}
127 	clip_cur = clip_top = NULL;
128 }
129 
R_3D_EnterSkybox()130 void R_3D_EnterSkybox()
131 {
132 	HeightStack current;
133 
134 	current.height_top = height_top;
135 	current.height_cur = height_cur;
136 	current.height_max = height_max;
137 
138 	toplist.Push(current);
139 
140 	height_top = NULL;
141 	height_cur = NULL;
142 	height_max = -1;
143 
144 	CurrentSkybox++;
145 }
146 
R_3D_LeaveSkybox()147 void R_3D_LeaveSkybox()
148 {
149 	HeightStack current;
150 
151 	current.height_top = NULL;
152 	current.height_cur = NULL;
153 	current.height_max = -1;
154 
155 	toplist.Pop(current);
156 
157 	height_top = current.height_top;
158 	height_cur = current.height_cur;
159 	height_max = current.height_max;
160 
161 	CurrentSkybox--;
162 }
163 
164