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