bspx stuff into its own file

change the printing to be less redundant on BSP version
This commit is contained in:
Jonathan 2022-06-16 10:59:22 -04:00
parent f53a6a19fe
commit 740ab24626
3 changed files with 120 additions and 87 deletions

View File

@ -1252,8 +1252,8 @@ static const gamedef_h2_t gamedef_h2;
static const gamedef_hl_t gamedef_hl;
static const gamedef_q2_t gamedef_q2;
const bspversion_t bspver_generic{NO_VERSION, NO_VERSION, "mbsp", "generic BSP", {}, &gamedef_generic};
const bspversion_t bspver_q1{BSPVERSION, NO_VERSION, "bsp29", "Quake BSP",
const bspversion_t bspver_generic{MBSPIDENT, std::nullopt, "mbsp", "generic BSP", {}, &gamedef_generic};
const bspversion_t bspver_q1{BSPVERSION, std::nullopt, "bsp29", "Quake BSP",
{
{"entities", sizeof(char)},
{"planes", sizeof(dplane_t)},
@ -1272,7 +1272,7 @@ const bspversion_t bspver_q1{BSPVERSION, NO_VERSION, "bsp29", "Quake BSP",
{"models", sizeof(dmodelq1_t)},
},
&gamedef_q1, &bspver_bsp2};
const bspversion_t bspver_bsp2{BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2",
const bspversion_t bspver_bsp2{BSP2VERSION, std::nullopt, "bsp2", "Quake BSP2",
{
{"entities", sizeof(char)},
{"planes", sizeof(dplane_t)},
@ -1291,7 +1291,7 @@ const bspversion_t bspver_bsp2{BSP2VERSION, NO_VERSION, "bsp2", "Quake BSP2",
{"models", sizeof(dmodelq1_t)},
},
&gamedef_q1};
const bspversion_t bspver_bsp2rmq{BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake BSP2-RMQ",
const bspversion_t bspver_bsp2rmq{BSP2RMQVERSION, std::nullopt, "bsp2rmq", "Quake BSP2-RMQ",
{
{"entities", sizeof(char)},
{"planes", sizeof(dplane_t)},
@ -1311,7 +1311,7 @@ const bspversion_t bspver_bsp2rmq{BSP2RMQVERSION, NO_VERSION, "bsp2rmq", "Quake
},
&gamedef_q1};
/* Hexen II doesn't use a separate version, but we can still use a separate tag/name for it */
const bspversion_t bspver_h2{BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP",
const bspversion_t bspver_h2{BSPVERSION, std::nullopt, "hexen2", "Hexen II BSP",
{
{"entities", sizeof(char)},
{"planes", sizeof(dplane_t)},
@ -1330,7 +1330,7 @@ const bspversion_t bspver_h2{BSPVERSION, NO_VERSION, "hexen2", "Hexen II BSP",
{"models", sizeof(dmodelh2_t)},
},
&gamedef_h2, &bspver_h2bsp2};
const bspversion_t bspver_h2bsp2{BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen II BSP2",
const bspversion_t bspver_h2bsp2{BSP2VERSION, std::nullopt, "hexen2bsp2", "Hexen II BSP2",
{
{"entities", sizeof(char)},
{"planes", sizeof(dplane_t)},
@ -1349,7 +1349,7 @@ const bspversion_t bspver_h2bsp2{BSP2VERSION, NO_VERSION, "hexen2bsp2", "Hexen I
{"models", sizeof(dmodelh2_t)},
},
&gamedef_h2};
const bspversion_t bspver_h2bsp2rmq{BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq", "Hexen II BSP2-RMQ",
const bspversion_t bspver_h2bsp2rmq{BSP2RMQVERSION, std::nullopt, "hexen2bsp2rmq", "Hexen II BSP2-RMQ",
{
{"entities", sizeof(char)},
{"planes", sizeof(dplane_t)},
@ -1368,7 +1368,7 @@ const bspversion_t bspver_h2bsp2rmq{BSP2RMQVERSION, NO_VERSION, "hexen2bsp2rmq",
{"models", sizeof(dmodelh2_t)},
},
&gamedef_h2};
const bspversion_t bspver_hl{BSPHLVERSION, NO_VERSION, "hl", "Half-Life BSP", bspver_q1.lumps, &gamedef_hl};
const bspversion_t bspver_hl{BSPHLVERSION, std::nullopt, "hl", "Half-Life BSP", bspver_q1.lumps, &gamedef_hl};
const bspversion_t bspver_q2{Q2_BSPIDENT, Q2_BSPVERSION, "q2bsp", "Quake II BSP",
{
{"entities", sizeof(char)},
@ -1529,7 +1529,7 @@ std::string contentflags_t::to_string(const gamedef_t *game) const
return s;
}
static bool BSPVersionSupported(int32_t ident, int32_t version, const bspversion_t **out_version)
static bool BSPVersionSupported(int32_t ident, std::optional<int32_t> version, const bspversion_t **out_version)
{
for (const bspversion_t *bspver : bspversions) {
if (bspver->ident == ident && bspver->version == version) {
@ -1976,7 +1976,7 @@ void LoadBSPFile(fs::path &filename, bspdata_t *bspdata)
dheader_t q1header;
stream >= q1header;
temp_version.version = NO_VERSION;
temp_version.version = std::nullopt;
std::copy(q1header.lumps.begin(), q1header.lumps.end(), std::back_inserter(lumps));
}
@ -2075,7 +2075,7 @@ private:
const lumpspec_t &lumpspec = version->lumps.begin()[lump_num];
lump_t *lumps;
if (version->version != NO_VERSION) {
if (version->version.has_value()) {
lumps = q2header.lumps.data();
} else {
lumps = q1header.lumps.data();
@ -2112,7 +2112,7 @@ private:
Q_assert(lumpspec.size == 1);
if (version->version != NO_VERSION) {
if (version->version.has_value()) {
lumps = q2header.lumps.data();
} else {
lumps = q1header.lumps.data();
@ -2144,7 +2144,7 @@ private:
Q_assert(lumpspec.size == 1);
if (version->version != NO_VERSION) {
if (version->version.has_value()) {
lumps = q2header.lumps.data();
} else {
lumps = q1header.lumps.data();
@ -2269,11 +2269,11 @@ void WriteBSPFile(const fs::path &filename, bspdata_t *bspdata)
// headers are union'd, so this sets both
bspfile.q2header.ident = bspfile.version->ident;
if (bspfile.version->version != NO_VERSION) {
bspfile.q2header.version = bspfile.version->version;
if (bspfile.version->version.has_value()) {
bspfile.q2header.version = bspfile.version->version.value();
}
logging::print("Writing {} as BSP version {}\n", filename, *bspdata->version);
logging::print("Writing {} as {}\n", filename, *bspdata->version);
bspfile.stream.open(filename, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
if (!bspfile.stream)
@ -2282,7 +2282,7 @@ void WriteBSPFile(const fs::path &filename, bspdata_t *bspdata)
bspfile.stream << endianness<std::endian::little>;
/* Save header space, updated after adding the lumps */
if (bspfile.version->version != NO_VERSION) {
if (bspfile.version->version.has_value()) {
bspfile.stream <= bspfile.q2header;
} else {
bspfile.stream <= bspfile.q1header;
@ -2296,7 +2296,7 @@ void WriteBSPFile(const fs::path &filename, bspdata_t *bspdata)
bspfile.stream.seekp(0);
// write the real header
if (bspfile.version->version != NO_VERSION) {
if (bspfile.version->version.has_value()) {
bspfile.stream <= bspfile.q2header;
} else {
bspfile.stream <= bspfile.q1header;

View File

@ -41,6 +41,8 @@ struct lump_t
auto stream_data() { return std::tie(fileofs, filelen); }
};
constexpr int32_t MBSPIDENT = -1;
constexpr int32_t BSPVERSION = 29;
constexpr int32_t BSP2RMQVERSION = (('B' << 24) | ('S' << 16) | ('P' << 8) | '2');
constexpr int32_t BSP2VERSION = ('B' | ('S' << 8) | ('P' << 16) | ('2' << 24));
@ -96,31 +98,6 @@ enum q2_lump_t
Q2_HEADER_LUMPS
};
struct bspx_header_t
{
std::array<char, 4> id = {'B', 'S', 'P', 'X'}; //'BSPX'
uint32_t numlumps;
bspx_header_t(uint32_t numlumps) : numlumps(numlumps) { }
auto stream_data() { return std::tie(id, numlumps); }
};
struct bspx_lump_t
{
std::array<char, 24> lumpname{};
uint32_t fileofs;
uint32_t filelen;
auto stream_data() { return std::tie(lumpname, fileofs, filelen); }
};
struct lumpspec_t
{
const char *name;
size_t size;
};
// helper functions to quickly numerically cast mins/maxs
// and floor/ceil them in the case of float -> integral
template<typename T, typename F>
@ -1673,43 +1650,7 @@ struct q2_dheader_t
auto stream_data() { return std::tie(ident, version, lumps); }
};
/* ========================================================================= */
// BRUSHLIST BSPX lump
struct bspxbrushes_permodel
{
int32_t ver;
int32_t modelnum;
int32_t numbrushes;
int32_t numfaces;
auto stream_data() { return std::tie(ver, modelnum, numbrushes, numfaces); }
};
struct bspxbrushes_perbrush
{
aabb3f bounds;
int16_t contents;
uint16_t numfaces;
auto stream_data() { return std::tie(bounds, contents, numfaces); }
};
using bspxbrushes_perface = qplane3f;
// BSPX data
struct bspxentry_t
{
std::unique_ptr<uint8_t[]> lumpdata;
size_t lumpsize;
// bspxentry_t takes ownership over the pointer and will
// free it automatically.
bspxentry_t(void *lumpdata, size_t lumpsize) : lumpdata(reinterpret_cast<uint8_t *>(lumpdata)), lumpsize(lumpsize)
{
}
};
#include "bspxfile.hh"
struct bspdata_t
{
@ -1821,15 +1762,22 @@ struct gamedef_t
virtual void print_content_stats(const std::any &stats, const char *what) const = 0;
};
constexpr int32_t NO_VERSION = -1;
// Lump specification; stores the name and size
// of an individual entry in the lump. Count is
// calculated as (lump_size / size)
struct lumpspec_t
{
const char *name;
size_t size;
};
// BSP version struct & instances
struct bspversion_t
{
/* identifier value, the first int32_t in the header */
int32_t ident;
/* version value, if supported; use NO_VERSION if a version is not required */
int32_t version;
/* version value, if supported */
std::optional<int32_t> version;
/* short name used for command line args, etc */
const char *short_name;
/* full display name for printing */
@ -1852,14 +1800,17 @@ struct fmt::formatter<bspversion_t>
auto format(const bspversion_t &v, FormatContext &ctx) -> decltype(ctx.out())
{
if (v.name) {
return format_to(ctx.out(), "{}", v.name);
format_to(ctx.out(), "{} ", v.name);
}
if (v.version != NO_VERSION) {
return format_to(ctx.out(), "{}:{}", v.version, v.ident);
// Q2-esque BSPs are printed as, ex, IBSP:38
if (v.version.has_value()) {
char ident[5] = { (char) (v.ident & 0xFF), (char) ((v.ident >> 8) & 0xFF), (char) ((v.ident >> 16) & 0xFF), (char) ((v.ident >> 24) & 0xFF), '\0' };
return format_to(ctx.out(), "{}:{}", ident, v.version.value());
}
return format_to(ctx.out(), "{}", v.version, v.ident);
// Q1-esque BSPs are printed as, ex, 29
return format_to(ctx.out(), "{}", v.version.value());
}
};

View File

@ -0,0 +1,82 @@
/* Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
#pragma once
#include <array>
#include <cstdint>
#include <common/aabb.hh>
#include <memory>
/* ========================================================================= */
struct bspx_header_t
{
std::array<char, 4> id = {'B', 'S', 'P', 'X'}; //'BSPX'
uint32_t numlumps;
constexpr bspx_header_t(uint32_t numlumps) : numlumps(numlumps) { }
auto stream_data() { return std::tie(id, numlumps); }
};
struct bspx_lump_t
{
std::array<char, 24> lumpname{};
uint32_t fileofs;
uint32_t filelen;
auto stream_data() { return std::tie(lumpname, fileofs, filelen); }
};
// BRUSHLIST BSPX lump
struct bspxbrushes_permodel
{
int32_t ver;
int32_t modelnum;
int32_t numbrushes;
int32_t numfaces;
auto stream_data() { return std::tie(ver, modelnum, numbrushes, numfaces); }
};
struct bspxbrushes_perbrush
{
aabb3f bounds;
int16_t contents;
uint16_t numfaces;
auto stream_data() { return std::tie(bounds, contents, numfaces); }
};
using bspxbrushes_perface = qplane3f;
// BSPX data
struct bspxentry_t
{
std::unique_ptr<uint8_t[]> lumpdata;
size_t lumpsize;
// bspxentry_t takes ownership over the pointer and will
// free it automatically.
inline bspxentry_t(void *lumpdata, size_t lumpsize) : lumpdata(reinterpret_cast<uint8_t *>(lumpdata)), lumpsize(lumpsize)
{
}
};