Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)


# Options
# Options (General)
option(SOURCEPP_USE_DMXPP "Build dmxpp library" ON)
option(SOURCEPP_USE_FGDPP "Build fgdpp library" ON)
option(SOURCEPP_USE_STUDIOMODELPP "Build studiomodelpp library" ON)
option(SOURCEPP_USE_VMFPP "Build vmfpp library" ON)
option(SOURCEPP_BUILD_TESTS "Build tests for enabled libraries" OFF)


# Options (Library)
option(FGDPP_ENABLE_SPEN_FGD_SUPPORT "Enable support for FGD alterations (https://github.com/TeamSpen210/HammerAddons/wiki/Unified-FGD) made by TeamSpen's HammerAddons. Fully backwards compatible with Valve's FGD standard." OFF)


# BufferStream
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src/thirdparty/bufferstream")

Expand Down Expand Up @@ -66,6 +71,18 @@ if(SOURCEPP_USE_DMXPP)
endif()


# fgdpp
if(SOURCEPP_USE_FGDPP)
add_pretty_parser(fgdpp SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/include/fgdpp/structs/entityproperties.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/fgdpp/fgdpp.h"
"${CMAKE_CURRENT_SOURCE_DIR}/src/fgdpp/fgdpp.cpp")
if(FGDPP_ENABLE_SPEN_FGD_SUPPORT)
target_compile_definitions(fgdpp PUBLIC FGDPP_UNIFIED_FGD)
endif()
endif()


# studiomodelpp
if(SOURCEPP_USE_STUDIOMODELPP)
add_pretty_parser(studiomodelpp SOURCES
Expand Down
32 changes: 8 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,11 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
Looking for more parsers in this vein? Try my other project which relies on this one,
[VPKEdit](https://github.com/craftablescience/VPKEdit)! It's a library too, not just a GUI.

## Supported Formats
This repository contains the following parsers:

### dmxpp
A parser for KV2/DMX files.

Currently supports:
- Binary
- v1
- v2
- v3
- v4
- v5

### studiomodelpp
A parser for the various Source engine model formats.

Currently supports:
- MDL v44-v49
- VTX v7
- VVD v4

### vmfpp
A parser for uncompiled Source 1 map files. Supports any VMF.
### Supported Formats

| Library Name | Supports | Read | Write | Author(s) |
|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----:|:-----:|----------------------------|
| dmxpp | [DMX](https://developer.valvesoftware.com/wiki/DMX) Binary v1-5 | ✅ | ❌ | @craftablescience |
| fgdpp | &bull; [Valve FGD syntax](https://developer.valvesoftware.com/wiki/FGD)<br>&bull; [TeamSpen's Unified FGD syntax](https://github.com/TeamSpen210/HammerAddons/wiki/Unified-FGD) | ✅ | ❌ | @Trico-Everfire |
| studiomodelpp | &bull; [MDL](https://developer.valvesoftware.com/wiki/MDL_(Source)) v44-49<br>&bull; [VTX](https://developer.valvesoftware.com/wiki/VTX) v7<br>&bull; [VVD](https://developer.valvesoftware.com/wiki/VVD) v4 | ✅ | ❌ | @craftablescience |
| vmfpp | Any [VMF](https://developer.valvesoftware.com/wiki/VMF_(Valve_Map_Format)) | ✅ | ❌ | @Galaco, @craftablescience |
62 changes: 62 additions & 0 deletions include/fgdpp/fgdpp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include <string>
#include <string_view>
#include <vector>

#include "structs/entityproperties.h"

namespace fgdpp {

class FGD {
std::string rawFGDFile;

//TOKENIZER
public:
enum TokenType {
COMMENT = 0, // //
DEFINITION, // @something
EQUALS, // =
OPEN_BRACE, // {
CLOSE_BRACE, // }
OPEN_BRACKET, // [
CLOSE_BRACKET, // ]
OPEN_PARENTHESIS, // (
CLOSE_PARENTHESIS, // )
COMMA, // ,
STRING, // "something"
PLUS, // +
LITERAL, // anything that isn't any of the other tokens.
COLUMN, // :
NUMBER, // numbers -200000 ... 0 ... 2000000
};

struct Token {
TokenType type;
Range range;
std::string_view string;
int line;
ParseError associatedError;
};

std::vector<Token> tokenList;

public:
FGD(std::string_view path, bool parseIncludes);

private:
bool TokenizeFile();

//PARSER.
public:
FGDFile FGDFileContents;
ParsingError parseError{ParseError::NO_ERROR, 0, {0, 0}};

bool ParseFile();

#ifdef FGDPP_UNIFIED_FGD
bool TagListDelimiter(std::vector<Token>::const_iterator& iter, TagList& tagList);
#endif
};

} // namespace fgdpp
159 changes: 159 additions & 0 deletions include/fgdpp/structs/entityproperties.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#pragma once

#include <string_view>
#include <vector>

namespace fgdpp {

enum class ParseError {
NO_ERROR = 0,
TOKENIZATION_ERROR,
INVALID_DEFINITION,
INVALID_EQUALS,
INVALID_OPEN_BRACE,
INVALID_CLOSE_BRACE,
INVALID_OPEN_BRACKET,
INVALID_CLOSE_BRACKET,
INVALID_OPEN_PARENTHESIS,
INVALID_CLOSE_PARENTHESIS,
INVALID_COMMA,
INVALID_STRING,
INVALID_PLUS,
INVALID_LITERAL,
INVALID_COLUMN,
INVALID_NUMBER,
FAILED_TO_OPEN,
PREMATURE_EOF,
};

struct Range {
int start;
int end;
};

struct ParsingError {
ParseError err;
int line;
Range span;
};

#ifdef FGDPP_UNIFIED_FGD
struct TagList {
std::vector<std::string_view> tags;
};
#endif

struct ClassProperty {
std::vector<std::string_view> properties;
};

struct ClassProperties {
std::string_view name;
std::vector<ClassProperty> classProperties;
};

enum class EntityIOPropertyType {
t_string = 0,
t_integer,
t_float,
t_bool,
t_void,
t_script,
t_vector,
t_target_destination,
t_color255,
t_custom,
};

struct Choice {
std::string_view value;
std::string_view displayName;
#ifdef FGDPP_UNIFIED_FGD
TagList tagList;
#endif
};

struct Flag {
int value;
bool checked;
std::string_view displayName;
#ifdef FGDPP_UNIFIED_FGD
TagList tagList;
#endif
};

struct EntityProperties {
std::string_view propertyName;
std::string_view type;
std::string_view displayName; // The following 3 are optional and may be empty as a result.
std::string_view defaultValue;
std::vector<std::string_view> propertyDescription;
bool readOnly;
bool reportable;

#ifdef FGDPP_UNIFIED_FGD
TagList tagList;
#endif

int choiceCount; // This is a special case if the EntityPropertyType is t_choices
std::vector<Choice> choices;

int flagCount; // This is a special case if the EntityPropertyType is t_flags
std::vector<Flag> flags;
};

enum class IO {
INPUT = 0,
OUTPUT,
};

struct InputOutput {
std::string_view name;
std::vector<std::string_view> description;
IO putType;
std::string_view stringType;
EntityIOPropertyType type;
#ifdef FGDPP_UNIFIED_FGD
TagList tagList;
#endif
};

#ifdef FGDPP_UNIFIED_FGD
struct EntityResource {
std::string_view key;
std::string_view value;
TagList tagList;
};
#endif

struct Entity {
std::string_view type;
std::vector<ClassProperties> classProperties;
std::string_view entityName;
std::vector<std::string_view> entityDescription;
std::vector<EntityProperties> entityProperties;
std::vector<InputOutput> inputOutput;
#ifdef FGDPP_UNIFIED_FGD
std::vector<EntityResource> resources;
#endif
};

struct AutoVisGroupChild {
std::string_view name;
std::vector<std::string_view> children;
};

struct AutoVisGroup {
std::string_view name;
struct std::vector<AutoVisGroupChild> children;
};

struct FGDFile {
Range mapSize{0,0};
std::vector<Entity> entities;
std::vector<std::string_view> materialExclusions;
std::vector<std::string_view> includes;
std::vector<AutoVisGroup> autoVisGroups;
};

} // namespace fgdpp
Loading