the old Safe read/writes are gonedy now
This commit is contained in:
parent
62f5867581
commit
e57633bbca
62
common/fs.cc
62
common/fs.cc
|
|
@ -322,65 +322,3 @@ data load(const path &p)
|
||||||
return arch->load(filename);
|
return arch->load(filename);
|
||||||
}
|
}
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
|
|
||||||
qfile_t SafeOpenWrite(const fs::path &filename)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
f = _wfopen(filename.c_str(), L"wb");
|
|
||||||
#else
|
|
||||||
f = fopen(filename.string().c_str(), "wb");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!f)
|
|
||||||
FError("Error opening {}: {}", filename, strerror(errno));
|
|
||||||
|
|
||||||
return {f, fclose};
|
|
||||||
}
|
|
||||||
|
|
||||||
qfile_t SafeOpenRead(const fs::path &filename, bool must_exist)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
f = _wfopen(filename.c_str(), L"rb");
|
|
||||||
#else
|
|
||||||
f = fopen(filename.string().c_str(), "rb");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!f) {
|
|
||||||
if (must_exist)
|
|
||||||
FError("Error opening {}: {}", filename, strerror(errno));
|
|
||||||
|
|
||||||
return {nullptr, nullptr};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {f, fclose};
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SafeRead(const qfile_t &f, void *buffer, size_t count)
|
|
||||||
{
|
|
||||||
if (fread(buffer, 1, count, f.get()) != (size_t)count)
|
|
||||||
FError("File read failure");
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SafeWrite(const qfile_t &f, const void *buffer, size_t count)
|
|
||||||
{
|
|
||||||
if (fwrite(buffer, 1, count, f.get()) != (size_t)count)
|
|
||||||
FError("File write failure");
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SafeSeek(const qfile_t &f, long offset, int32_t origin)
|
|
||||||
{
|
|
||||||
fseek(f.get(), offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
long SafeTell(const qfile_t &f)
|
|
||||||
{
|
|
||||||
return ftell(f.get());
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ struct fmt::formatter<bspversion_t>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Q1-esque BSPs are printed as, ex, 29
|
// Q1-esque BSPs are printed as, ex, 29
|
||||||
return format_to(ctx.out(), "{}", v.version.value());
|
return format_to(ctx.out(), "{}", v.ident);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,15 +124,6 @@ inline fs::path DefaultExtension(const fs::path &path, const fs::path &extension
|
||||||
return fs::path(path).replace_extension(extension);
|
return fs::path(path).replace_extension(extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
using qfile_t = std::unique_ptr<FILE, decltype(&fclose)>;
|
|
||||||
|
|
||||||
qfile_t SafeOpenWrite(const fs::path &filename);
|
|
||||||
qfile_t SafeOpenRead(const fs::path &filename, bool must_exist = false);
|
|
||||||
size_t SafeRead(const qfile_t &f, void *buffer, size_t count);
|
|
||||||
size_t SafeWrite(const qfile_t &f, const void *buffer, size_t count);
|
|
||||||
void SafeSeek(const qfile_t &f, long offset, int32_t origin);
|
|
||||||
long SafeTell(const qfile_t &f);
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
// TODO: no wchar_t support in this version apparently
|
// TODO: no wchar_t support in this version apparently
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,17 @@ struct litheader_t
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char ident[4];
|
std::array<char, 4> ident = { 'Q', 'L', 'I', 'T' };
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
|
auto stream_data() { return std::tie(ident, version); }
|
||||||
} v1;
|
} v1;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int numsurfs;
|
int numsurfs;
|
||||||
int lmsamples;
|
int lmsamples;
|
||||||
|
|
||||||
|
auto stream_data() { return std::tie(numsurfs, lmsamples); }
|
||||||
} v2;
|
} v2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,22 +24,25 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <fstream>
|
||||||
#include "common/cmdlib.hh"
|
#include "common/cmdlib.hh"
|
||||||
#include "common/fs.hh"
|
#include "common/fs.hh"
|
||||||
|
|
||||||
// Texture data stored for quick searching
|
// Texture data stored for quick searching
|
||||||
struct texture_t
|
struct texture_t
|
||||||
{
|
{
|
||||||
char name[16];
|
std::string name;
|
||||||
int width, height;
|
int width, height;
|
||||||
};
|
};
|
||||||
|
|
||||||
// WAD Format
|
// WAD Format
|
||||||
struct wadinfo_t
|
struct wadinfo_t
|
||||||
{
|
{
|
||||||
char identification[4]; // should be WAD2
|
std::array<char, 4> identification; // should be WAD2
|
||||||
int numlumps;
|
int numlumps;
|
||||||
int infotableofs;
|
int infotableofs;
|
||||||
|
|
||||||
|
auto stream_data() { return std::tie(identification, numlumps, infotableofs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lumpinfo_t
|
struct lumpinfo_t
|
||||||
|
|
@ -50,7 +53,9 @@ struct lumpinfo_t
|
||||||
char type;
|
char type;
|
||||||
char compression;
|
char compression;
|
||||||
char pad1, pad2;
|
char pad1, pad2;
|
||||||
char name[16]; // must be null terminated
|
std::array<char, 16> name; // must be null terminated
|
||||||
|
|
||||||
|
auto stream_data() { return std::tie(filepos, disksize, size, type, compression, pad1, pad2, name); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wad_t
|
struct wad_t
|
||||||
|
|
@ -59,7 +64,7 @@ struct wad_t
|
||||||
int version;
|
int version;
|
||||||
std::unordered_map<std::string, lumpinfo_t, case_insensitive_hash, case_insensitive_equal> lumps;
|
std::unordered_map<std::string, lumpinfo_t, case_insensitive_hash, case_insensitive_equal> lumps;
|
||||||
std::unordered_map<std::string, texture_t, case_insensitive_hash, case_insensitive_equal> textures;
|
std::unordered_map<std::string, texture_t, case_insensitive_hash, case_insensitive_equal> textures;
|
||||||
qfile_t file = {nullptr, nullptr};
|
std::ifstream file;
|
||||||
};
|
};
|
||||||
|
|
||||||
void WADList_Init(const std::string_view &wadstring);
|
void WADList_Init(const std::string_view &wadstring);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
See file, 'COPYING', for details.
|
See file, 'COPYING', for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include <light/litfile.hh>
|
#include <light/litfile.hh>
|
||||||
#include <light/light.hh>
|
#include <light/light.hh>
|
||||||
|
|
||||||
|
|
@ -31,47 +33,38 @@ void WriteLitFile(const mbsp_t *bsp, facesup_t *facesup, const fs::path &filenam
|
||||||
fs::path litname = filename;
|
fs::path litname = filename;
|
||||||
litname.replace_extension("lit");
|
litname.replace_extension("lit");
|
||||||
|
|
||||||
header.v1.ident[0] = 'Q';
|
header.v1.version = version;
|
||||||
header.v1.ident[1] = 'L';
|
header.v2.numsurfs = bsp->dfaces.size();
|
||||||
header.v1.ident[2] = 'I';
|
header.v2.lmsamples = bsp->dlightdata.size();
|
||||||
header.v1.ident[3] = 'T';
|
|
||||||
header.v1.version = LittleLong(version);
|
|
||||||
header.v2.numsurfs = LittleLong(bsp->dfaces.size());
|
|
||||||
header.v2.lmsamples = LittleLong(bsp->dlightdata.size());
|
|
||||||
|
|
||||||
logging::print("Writing {}\n", litname);
|
logging::print("Writing {}\n", litname);
|
||||||
auto litfile = SafeOpenWrite(litname);
|
std::ofstream litfile(litname, std::ios_base::out | std::ios_base::binary);
|
||||||
SafeWrite(litfile, &header.v1, sizeof(header.v1));
|
litfile <= header.v1;
|
||||||
if (version == 2) {
|
if (version == 2) {
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
unsigned int *offsets = new unsigned int[bsp->dfaces.size()];
|
litfile <= header.v2;
|
||||||
unsigned short *extents = new unsigned short[2 * bsp->dfaces.size()];
|
|
||||||
unsigned char *styles = new unsigned char[4 * bsp->dfaces.size()];
|
|
||||||
unsigned char *shifts = new unsigned char[bsp->dfaces.size()];
|
|
||||||
for (i = 0; i < bsp->dfaces.size(); i++) {
|
for (i = 0; i < bsp->dfaces.size(); i++) {
|
||||||
offsets[i] = LittleLong(facesup[i].lightofs);
|
litfile <= facesup[i].lightofs;
|
||||||
styles[i * 4 + 0] = LittleShort(facesup[i].styles[0]);
|
for (int j = 0; j < 4; j++) {
|
||||||
styles[i * 4 + 1] = LittleShort(facesup[i].styles[1]);
|
litfile <= facesup[i].styles[j];
|
||||||
styles[i * 4 + 2] = LittleShort(facesup[i].styles[2]);
|
}
|
||||||
styles[i * 4 + 3] = LittleShort(facesup[i].styles[3]);
|
for (int j = 0; j < 2; j++) {
|
||||||
extents[i * 2 + 0] = LittleShort(facesup[i].extent[0]);
|
litfile <= facesup[i].extent[j];
|
||||||
extents[i * 2 + 1] = LittleShort(facesup[i].extent[1]);
|
}
|
||||||
j = 0;
|
j = 0;
|
||||||
while (nth_bit(j) < facesup[i].lmscale)
|
while (nth_bit(j) < facesup[i].lmscale)
|
||||||
j++;
|
j++;
|
||||||
shifts[i] = j;
|
litfile <= (uint8_t) j;
|
||||||
}
|
}
|
||||||
SafeWrite(litfile, &header.v2, sizeof(header.v2));
|
litfile.write((const char *) lit_filebase, bsp->dlightdata.size() * 3);
|
||||||
SafeWrite(litfile, offsets, bsp->dfaces.size() * sizeof(*offsets));
|
litfile.write((const char *) lux_filebase, bsp->dlightdata.size() * 3);
|
||||||
SafeWrite(litfile, extents, 2 * bsp->dfaces.size() * sizeof(*extents));
|
}
|
||||||
SafeWrite(litfile, styles, 4 * bsp->dfaces.size() * sizeof(*styles));
|
else
|
||||||
SafeWrite(litfile, shifts, bsp->dfaces.size() * sizeof(*shifts));
|
litfile.write((const char *) lit_filebase, bsp->dlightdata.size() * 3);
|
||||||
SafeWrite(litfile, lit_filebase, bsp->dlightdata.size() * 3);
|
|
||||||
SafeWrite(litfile, lux_filebase, bsp->dlightdata.size() * 3);
|
|
||||||
} else
|
|
||||||
SafeWrite(litfile, lit_filebase, bsp->dlightdata.size() * 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
void WriteLuxFile(const mbsp_t *bsp, const fs::path &filename, int version)
|
void WriteLuxFile(const mbsp_t *bsp, const fs::path &filename, int version)
|
||||||
{
|
{
|
||||||
litheader_t header;
|
litheader_t header;
|
||||||
|
|
@ -79,13 +72,9 @@ void WriteLuxFile(const mbsp_t *bsp, const fs::path &filename, int version)
|
||||||
fs::path luxname = filename;
|
fs::path luxname = filename;
|
||||||
luxname.replace_extension("lux");
|
luxname.replace_extension("lux");
|
||||||
|
|
||||||
header.v1.ident[0] = 'Q';
|
header.v1.version = version;
|
||||||
header.v1.ident[1] = 'L';
|
|
||||||
header.v1.ident[2] = 'I';
|
|
||||||
header.v1.ident[3] = 'T';
|
|
||||||
header.v1.version = LittleLong(version);
|
|
||||||
|
|
||||||
auto luxfile = SafeOpenWrite(luxname);
|
std::ofstream luxfile(luxname, std::ios_base::out | std::ios_base::binary);
|
||||||
SafeWrite(luxfile, &header.v1, sizeof(header.v1));
|
luxfile <= header.v1;
|
||||||
SafeWrite(luxfile, lux_filebase, bsp->dlightdata.size() * 3);
|
luxfile.write((const char *) lux_filebase, bsp->dlightdata.size() * 3);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
55
qbsp/wad.cc
55
qbsp/wad.cc
|
|
@ -59,43 +59,47 @@ uint8_t thepalette[768] = // Quake palette
|
||||||
|
|
||||||
static bool WAD_LoadInfo(wad_t &wad, bool external)
|
static bool WAD_LoadInfo(wad_t &wad, bool external)
|
||||||
{
|
{
|
||||||
wadinfo_t *hdr = &wad.header;
|
wadinfo_t &hdr = wad.header;
|
||||||
int i, len;
|
int i;
|
||||||
dmiptex_t miptex;
|
dmiptex_t miptex;
|
||||||
|
|
||||||
external |= options.notextures.value();
|
external |= options.notextures.value();
|
||||||
|
|
||||||
len = SafeRead(wad.file, hdr, sizeof(wadinfo_t));
|
wad.file >= hdr;
|
||||||
if (len != sizeof(wadinfo_t))
|
|
||||||
|
if (wad.file.bad())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wad.version = 0;
|
wad.version = 0;
|
||||||
if (!strncmp(hdr->identification, "WAD2", 4))
|
if (!strncmp(hdr.identification.data(), "WAD2", 4))
|
||||||
wad.version = 2;
|
wad.version = 2;
|
||||||
else if (!strncmp(hdr->identification, "WAD3", 4))
|
else if (!strncmp(hdr.identification.data(), "WAD3", 4))
|
||||||
wad.version = 3;
|
wad.version = 3;
|
||||||
if (!wad.version)
|
if (!wad.version)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SafeSeek(wad.file, hdr->infotableofs, SEEK_SET);
|
wad.file.seekg(hdr.infotableofs, std::ios_base::beg);
|
||||||
wad.lumps.reserve(wad.header.numlumps);
|
wad.lumps.reserve(wad.header.numlumps);
|
||||||
|
|
||||||
/* Get the dimensions and make a texture_t */
|
/* Get the dimensions and make a texture_t */
|
||||||
for (i = 0; i < wad.header.numlumps; i++) {
|
for (i = 0; i < wad.header.numlumps; i++) {
|
||||||
lumpinfo_t lump;
|
lumpinfo_t lump;
|
||||||
|
wad.file >= lump;
|
||||||
|
|
||||||
len = SafeRead(wad.file, &lump, sizeof(lump));
|
if (wad.file.bad())
|
||||||
if (len != sizeof(lump))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto restore_pos = SafeTell(wad.file);
|
std::streampos restore_pos = wad.file.tellg();
|
||||||
|
wad.file.seekg(lump.filepos, std::ios_base::beg);
|
||||||
|
wad.file >= miptex;
|
||||||
|
miptex.name[15] = '\0'; // just in case we encounter a bad name
|
||||||
|
|
||||||
SafeSeek(wad.file, lump.filepos, SEEK_SET);
|
if (wad.file.bad()) {
|
||||||
len = SafeRead(wad.file, &miptex, sizeof(miptex));
|
lump.size = 0;
|
||||||
|
wad.lumps.insert({lump.name.data(), lump});
|
||||||
if (len == sizeof(miptex)) {
|
} else {
|
||||||
int w = LittleLong(miptex.width);
|
int w = miptex.width;
|
||||||
int h = LittleLong(miptex.height);
|
int h = miptex.height;
|
||||||
lump.size =
|
lump.size =
|
||||||
sizeof(miptex) + (w >> 0) * (h >> 0) + (w >> 1) * (h >> 1) + (w >> 2) * (h >> 2) + (w >> 3) * (h >> 3);
|
sizeof(miptex) + (w >> 0) * (h >> 0) + (w >> 1) * (h >> 1) + (w >> 2) * (h >> 2) + (w >> 3) * (h >> 3);
|
||||||
if (options.target_game->id == GAME_HALF_LIFE)
|
if (options.target_game->id == GAME_HALF_LIFE)
|
||||||
|
|
@ -103,8 +107,7 @@ static bool WAD_LoadInfo(wad_t &wad, bool external)
|
||||||
lump.size = (lump.size + 3) & ~3; // keep things aligned if we can.
|
lump.size = (lump.size + 3) & ~3; // keep things aligned if we can.
|
||||||
|
|
||||||
texture_t tex;
|
texture_t tex;
|
||||||
memcpy(tex.name, miptex.name.data(), 16);
|
tex.name = miptex.name.data();
|
||||||
tex.name[15] = '\0';
|
|
||||||
tex.width = miptex.width;
|
tex.width = miptex.width;
|
||||||
tex.height = miptex.height;
|
tex.height = miptex.height;
|
||||||
wad.textures.insert({tex.name, tex});
|
wad.textures.insert({tex.name, tex});
|
||||||
|
|
@ -115,12 +118,9 @@ static bool WAD_LoadInfo(wad_t &wad, bool external)
|
||||||
|
|
||||||
// fmt::print("Created texture_t {} {} {}\n", tex->name, tex->width, tex->height);
|
// fmt::print("Created texture_t {} {} {}\n", tex->name, tex->width, tex->height);
|
||||||
wad.lumps.insert({tex.name, lump});
|
wad.lumps.insert({tex.name, lump});
|
||||||
} else {
|
|
||||||
lump.size = 0;
|
|
||||||
wad.lumps.insert({lump.name, lump});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeSeek(wad.file, restore_pos, SEEK_SET);
|
wad.file.seekg(restore_pos, std::ios_base::beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -130,7 +130,7 @@ static void WADList_OpenWad(const fs::path &fpath, bool external)
|
||||||
{
|
{
|
||||||
wad_t wad;
|
wad_t wad;
|
||||||
|
|
||||||
wad.file = SafeOpenRead(fpath);
|
wad.file.open(fpath, std::ios_base::in | std::ios_base::binary);
|
||||||
|
|
||||||
if (wad.file) {
|
if (wad.file) {
|
||||||
if (options.fVerbose)
|
if (options.fVerbose)
|
||||||
|
|
@ -142,7 +142,7 @@ static void WADList_OpenWad(const fs::path &fpath, bool external)
|
||||||
}
|
}
|
||||||
|
|
||||||
logging::print("WARNING: {} isn't a wadfile\n", fpath);
|
logging::print("WARNING: {} isn't a wadfile\n", fpath);
|
||||||
wad.file.reset();
|
wad.file.close();
|
||||||
} else {
|
} else {
|
||||||
// Message?
|
// Message?
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +196,7 @@ static const lumpinfo_t *WADList_FindTexture(const std::string &name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool WAD_LoadLump(const wad_t &wad, const char *name, miptexhl_t &dest)
|
static bool WAD_LoadLump(wad_t &wad, const char *name, miptexhl_t &dest)
|
||||||
{
|
{
|
||||||
auto it = wad.lumps.find(name);
|
auto it = wad.lumps.find(name);
|
||||||
|
|
||||||
|
|
@ -207,7 +207,7 @@ static bool WAD_LoadLump(const wad_t &wad, const char *name, miptexhl_t &dest)
|
||||||
|
|
||||||
auto &lump = it->second;
|
auto &lump = it->second;
|
||||||
|
|
||||||
SafeSeek(wad.file, lump.filepos, SEEK_SET);
|
wad.file.seekg(lump.filepos, std::ios_base::beg);
|
||||||
|
|
||||||
if (lump.disksize < sizeof(dmiptex_t)) {
|
if (lump.disksize < sizeof(dmiptex_t)) {
|
||||||
logging::print("Wad texture {} is invalid", name);
|
logging::print("Wad texture {} is invalid", name);
|
||||||
|
|
@ -215,7 +215,8 @@ static bool WAD_LoadLump(const wad_t &wad, const char *name, miptexhl_t &dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(lump.disksize);
|
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(lump.disksize);
|
||||||
size_t size = SafeRead(wad.file, buffer.get(), lump.disksize);
|
wad.file.read((char *) buffer.get(), lump.disksize);
|
||||||
|
size_t size = wad.file.gcount();
|
||||||
|
|
||||||
if (size != lump.disksize)
|
if (size != lump.disksize)
|
||||||
FError("Failure reading from file");
|
FError("Failure reading from file");
|
||||||
|
|
|
||||||
70
vis/vis.cc
70
vis/vis.cc
|
|
@ -598,6 +598,8 @@ void CalcVis(mbsp_t *bsp)
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
LoadPortals
|
LoadPortals
|
||||||
|
|
@ -605,26 +607,28 @@ void CalcVis(mbsp_t *bsp)
|
||||||
*/
|
*/
|
||||||
static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
||||||
{
|
{
|
||||||
int i, j, count;
|
int i, j;
|
||||||
portal_t *p;
|
portal_t *p;
|
||||||
leaf_t *l;
|
leaf_t *l;
|
||||||
char magic[80];
|
std::string magic;
|
||||||
int numpoints;
|
int numpoints;
|
||||||
int leafnums[2];
|
int leafnums[2];
|
||||||
qplane3d plane;
|
qplane3d plane;
|
||||||
qfile_t f = SafeOpenRead(name, true);
|
std::ifstream f(name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the portal file header
|
* Parse the portal file header
|
||||||
*/
|
*/
|
||||||
count = fscanf(f.get(), "%79s\n", magic);
|
std::getline(f, magic);
|
||||||
if (count != 1)
|
if (magic.empty()) {
|
||||||
FError("unknown header: {}\n", magic);
|
FError("unknown header/empty portal file {}\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(magic, PORTALFILE)) {
|
if (magic == PORTALFILE) {
|
||||||
count = fscanf(f.get(), "%i\n%i\n", &portalleafs, &numportals);
|
f >> portalleafs >> numportals;
|
||||||
if (count != 2)
|
|
||||||
FError("unable to parse {} HEADER\n", PORTALFILE);
|
if (f.bad())
|
||||||
|
FError("unable to parse {} header\n", PORTALFILE);
|
||||||
|
|
||||||
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
// since q2bsp has native cluster support, we shouldn't look at portalleafs_real at all.
|
// since q2bsp has native cluster support, we shouldn't look at portalleafs_real at all.
|
||||||
|
|
@ -636,23 +640,25 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
||||||
logging::print("{:6} leafs\n", portalleafs);
|
logging::print("{:6} leafs\n", portalleafs);
|
||||||
logging::print("{:6} portals\n", numportals);
|
logging::print("{:6} portals\n", numportals);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(magic, PORTALFILE2)) {
|
} else if (magic == PORTALFILE2) {
|
||||||
count = fscanf(f.get(), "%i\n%i\n%i\n", &portalleafs_real, &portalleafs, &numportals);
|
|
||||||
if (count != 3)
|
|
||||||
FError("unable to parse {} HEADER\n", PORTALFILE);
|
|
||||||
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
FError("{} can not be used with Q2\n", PORTALFILE2);
|
FError("{} can not be used with Q2\n", PORTALFILE2);
|
||||||
}
|
}
|
||||||
|
f >> portalleafs_real >> portalleafs >> numportals;
|
||||||
|
|
||||||
|
if (f.bad())
|
||||||
|
FError("unable to parse {} header\n", PORTALFILE);
|
||||||
logging::print("{:6} leafs\n", portalleafs_real);
|
logging::print("{:6} leafs\n", portalleafs_real);
|
||||||
logging::print("{:6} clusters\n", portalleafs);
|
logging::print("{:6} clusters\n", portalleafs);
|
||||||
logging::print("{:6} portals\n", numportals);
|
logging::print("{:6} portals\n", numportals);
|
||||||
} else if (!strcmp(magic, PORTALFILEAM)) {
|
} else if (magic == PORTALFILEAM) {
|
||||||
count = fscanf(f.get(), "%i\n%i\n%i\n", &portalleafs, &numportals, &portalleafs_real);
|
|
||||||
if (count != 3)
|
|
||||||
FError("unable to parse {} HEADER\n", PORTALFILE);
|
|
||||||
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||||
FError("{} can not be used with Q2\n", PORTALFILEAM);
|
FError("{} can not be used with Q2\n", PORTALFILEAM);
|
||||||
}
|
}
|
||||||
|
f >> portalleafs >> numportals >> portalleafs_real;
|
||||||
|
|
||||||
|
if (f.bad())
|
||||||
|
FError("unable to parse {} header\n", PORTALFILE);
|
||||||
logging::print("{:6} leafs\n", portalleafs_real);
|
logging::print("{:6} leafs\n", portalleafs_real);
|
||||||
logging::print("{:6} clusters\n", portalleafs);
|
logging::print("{:6} clusters\n", portalleafs);
|
||||||
logging::print("{:6} portals\n", numportals);
|
logging::print("{:6} portals\n", numportals);
|
||||||
|
|
@ -688,7 +694,8 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
||||||
vismap_end = vismap + bsp->dvis.bits.size();
|
vismap_end = vismap + bsp->dvis.bits.size();
|
||||||
|
|
||||||
for (i = 0, p = portals; i < numportals; i++) {
|
for (i = 0, p = portals; i < numportals; i++) {
|
||||||
if (fscanf(f.get(), "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1]) != 3)
|
f >> numpoints >> leafnums[0] >> leafnums[1];
|
||||||
|
if (f.bad())
|
||||||
FError("reading portal {}", i);
|
FError("reading portal {}", i);
|
||||||
if (numpoints > MAX_WINDING)
|
if (numpoints > MAX_WINDING)
|
||||||
FError("portal {} has too many points", i);
|
FError("portal {} has too many points", i);
|
||||||
|
|
@ -698,10 +705,17 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
||||||
winding_t &w = *(p->winding = std::make_shared<winding_t>(numpoints));
|
winding_t &w = *(p->winding = std::make_shared<winding_t>(numpoints));
|
||||||
|
|
||||||
for (j = 0; j < numpoints; j++) {
|
for (j = 0; j < numpoints; j++) {
|
||||||
if (fscanf(f.get(), "(%lf %lf %lf ) ", &w[j][0], &w[j][1], &w[j][2]) != 3)
|
while (!f.bad() && f.get() != '(')
|
||||||
|
;
|
||||||
|
|
||||||
|
f >> w[j][0] >> w[j][1] >> w[j][2];
|
||||||
|
|
||||||
|
while (!f.bad() && f.get() != ')')
|
||||||
|
;
|
||||||
|
|
||||||
|
if (f.bad())
|
||||||
FError("reading portal {}", i);
|
FError("reading portal {}", i);
|
||||||
}
|
}
|
||||||
fscanf(f.get(), "\n");
|
|
||||||
|
|
||||||
// calc plane
|
// calc plane
|
||||||
plane = w.plane();
|
plane = w.plane();
|
||||||
|
|
@ -752,12 +766,12 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(magic, PORTALFILE2)) {
|
if (magic == PORTALFILE2) {
|
||||||
for (i = 0; i < portalleafs; i++) {
|
for (i = 0; i < portalleafs; i++) {
|
||||||
while (1) {
|
while (1) {
|
||||||
int leafnum;
|
int leafnum;
|
||||||
count = fscanf(f.get(), "%i", &leafnum);
|
f >> leafnum;
|
||||||
if (!count || count == EOF)
|
if (f.bad() || f.eof())
|
||||||
break;
|
break;
|
||||||
if (leafnum < 0)
|
if (leafnum < 0)
|
||||||
break;
|
break;
|
||||||
|
|
@ -765,16 +779,16 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
||||||
FError("Invalid leaf number in cluster map ({} >= {})", leafnum, portalleafs_real);
|
FError("Invalid leaf number in cluster map ({} >= {})", leafnum, portalleafs_real);
|
||||||
bsp->dleafs[leafnum + 1].cluster = i;
|
bsp->dleafs[leafnum + 1].cluster = i;
|
||||||
}
|
}
|
||||||
if (count == EOF)
|
if (f.bad() || f.eof())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i < portalleafs)
|
if (i < portalleafs)
|
||||||
FError("Couldn't read cluster map ({} / {})\n", i, portalleafs);
|
FError("Couldn't read cluster map ({} / {})\n", i, portalleafs);
|
||||||
} else if (!strcmp(magic, PORTALFILEAM)) {
|
} else if (magic == PORTALFILEAM) {
|
||||||
for (i = 0; i < portalleafs_real; i++) {
|
for (i = 0; i < portalleafs_real; i++) {
|
||||||
int clusternum;
|
int clusternum;
|
||||||
count = fscanf(f.get(), "%i", &clusternum);
|
f >> clusternum;
|
||||||
if (!count || count == EOF) {
|
if (f.bad() || f.eof()) {
|
||||||
Error("Unexpected end of cluster map\n");
|
Error("Unexpected end of cluster map\n");
|
||||||
}
|
}
|
||||||
if (clusternum < 0 || clusternum >= portalleafs) {
|
if (clusternum < 0 || clusternum >= portalleafs) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue