engine: reject mbf21 and shit24 wads. there is no way to know if it is safe to ignore...
[k8vavoom.git] / source / maploader / mapload_decals.cpp
blob9c7480901f2025f58dde4c4ffe69629d306bab0e
1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
21 //**
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
26 #include <stdlib.h>
27 #include <string.h>
28 // we have to include it first, so map implementation will see our `GetTypeHash()`
29 #include "../../libs/core/hash/hashfunc.h"
31 struct __attribute__((packed)) VectorInfo {
32 float xy[2];
33 //unsigned aidx;
34 unsigned lidx; // linedef index
35 VectorInfo *next;
37 inline bool operator == (const VectorInfo &vi) const noexcept { return (memcmp(xy, &vi.xy, sizeof(xy)) == 0); }
38 inline bool operator != (const VectorInfo &vi) const noexcept { return (memcmp(xy, &vi.xy, sizeof(xy)) != 0); }
40 static_assert(sizeof(VectorInfo) == sizeof(float)*2+sizeof(unsigned)*1+sizeof(void *), "oops");
42 static inline uint32_t GetTypeHash (const VectorInfo &vi) noexcept { return joaatHashBuf(vi.xy, sizeof(vi.xy)); }
45 // ////////////////////////////////////////////////////////////////////////// //
46 #include "../gamedefs.h"
49 //==========================================================================
51 // VLevel::BuildDecalsVVList
53 // build v1 and v2 lists (for decals)
55 //==========================================================================
56 void VLevel::BuildDecalsVVList () {
57 if (NumLines < 1) return; // just in case
59 // build hashes and lists
60 TMapNC<VectorInfo, unsigned> vmap; // value: index in in tarray
61 TArray<VectorInfo> va;
62 va.setLength(NumLines*2);
63 line_t *ld = Lines;
64 for (unsigned i = 0; i < (unsigned)NumLines; ++i, ++ld) {
65 ld->v1linesCount = ld->v2linesCount = 0;
66 ld->v1lines = ld->v2lines = nullptr;
67 for (unsigned vn = 0; vn < 2; ++vn) {
68 const unsigned aidx = i*2+vn;
69 VectorInfo *vi = &va[aidx];
70 const TVec *vertex = (vn == 0 ? ld->v1 : ld->v2);
71 vi->xy[0] = vertex->x;
72 vi->xy[1] = vertex->y;
73 //vi->aidx = aidx;
74 vi->lidx = i;
75 vi->next = nullptr;
76 auto vaidxp = vmap.get(*vi);
77 if (vaidxp) {
78 //vassert(*vaidxp != vi->aidx);
79 VectorInfo *cv = &va[*vaidxp];
80 while (cv->next) {
81 //vassert(cv->aidx < aidx);
82 if (*cv != *vi) Sys_Error("VLevel::BuildDecalsVVList: OOPS(0)!");
83 cv = cv->next;
85 if (*cv != *vi) Sys_Error("VLevel::BuildDecalsVVList: OOPS(1)!");
86 cv->next = vi;
87 } else {
88 vmap.put(*vi, /*vi->*/aidx);
93 TArray<line_t *> wklist;
94 wklist.setLength(NumLines*2);
96 TArray<vuint8> wkhit;
97 wkhit.setLength(NumLines);
99 // fill linedef lists
100 ld = Lines;
101 for (unsigned i = 0; i < (unsigned)NumLines; ++i, ++ld) {
102 for (unsigned vn = 0; vn < 2; ++vn) {
103 memset(wkhit.ptr(), 0, wkhit.length()*sizeof(wkhit.ptr()[0]));
104 wkhit[i] = 1;
106 unsigned count = 0;
107 VectorInfo *vi = &va[i*2+vn];
108 auto vaidxp = vmap.get(*vi);
109 if (!vaidxp) Sys_Error("VLevel::BuildDecalsVVList: internal error (0)");
110 VectorInfo *cv = &va[*vaidxp];
111 while (cv) {
112 if (!wkhit[cv->lidx]) {
113 if (*cv != *vi) Sys_Error("VLevel::BuildDecalsVVList: OOPS(2)!");
114 wkhit[cv->lidx] = 1;
115 wklist[count++] = &Lines[cv->lidx];
117 cv = cv->next;
120 if (count > 0) {
121 line_t **list = new line_t *[count];
122 memcpy(list, wklist.ptr(), count*sizeof(line_t *));
123 if (vn == 0) {
124 ld->v1linesCount = count;
125 ld->v1lines = list;
126 } else {
127 ld->v2linesCount = count;
128 ld->v2lines = list;
136 //==========================================================================
138 // VLevel::PostProcessForDecals
140 //==========================================================================
141 void VLevel::PostProcessForDecals () {
142 GCon->Logf(NAME_Dev, "postprocessing level for faster decals");
144 for (auto &&line : allLines()) line.firstseg = nullptr;
146 GCon->Logf(NAME_Dev, "postprocessing level for faster decals: assigning segs");
147 // collect segments, so we won't go thru the all segs in decal spawner
148 for (auto &&seg : allSegs()) {
149 line_t *li = seg.linedef;
150 if (!li) continue;
151 //seg.lsnext = li->firstseg;
152 //li->firstseg = &seg;
153 seg_t *cs = li->firstseg;
154 if (cs) {
155 while (cs->lsnext) cs = cs->lsnext;
156 cs->lsnext = &seg;
157 } else {
158 li->firstseg = &seg;