From b95ce55edcabb7e9fcc6aa549498186b9faa602b Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 7 Dec 2024 18:01:03 +0200 Subject: [PATCH] maps: add materials support check for other games --- README.md | 3 +- src/common/header/flags.h | 76 ++++++++++++++++++++++++++++++++++ src/common/maps.c | 86 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 159 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 43a1a39f2..f66279972 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,8 @@ Goals: * [ ] MDA model skin selection by tag, * [ ] SDEF/MDA dynamicaly allocate list of skins, * [ ] Support material load textures/textureinfo.dat from Anachronox, -* [ ] Support textures/*/*.mat load from ReRelease, +* [*] Support textures/*/*.mat load from ReRelease (footstep), +* [ ] Support textures/*/*.mat load from ReRelease texture effects, * [ ] Support textures/*/*_glow.png load from ReRelease, * [ ] Support tactile/*/*.bnvib/.wav feedback load from ReRelease, * [ ] Fix physics with incorrect floor height in psx/base0.bsp, diff --git a/src/common/header/flags.h b/src/common/header/flags.h index 775146fab..4e1f20e94 100644 --- a/src/common/header/flags.h +++ b/src/common/header/flags.h @@ -211,6 +211,44 @@ static const int daikatana_flags[32] = { 0, /* 31: Unused */ }; +static const char *daikatana_material[] = { + NULL, /* 0: Emit light from the surface, brightness is + * specified in the 'value' field" */ + NULL, /* 1: Fullbright */ + NULL, /* 2: The surface is sky, the texture will not be drawn, + * but the background sky box is used instead */ + NULL, /* 3: The surface warps (like water textures do) */ + NULL, /* 4: The surface is 33% transparent */ + NULL, /* 5: The surface is 66% transparent */ + NULL, /* 6: The texture wraps in a downward 'flowing' pattern + * (warp must also be set) */ + NULL, /* 7: Used for non-fixed-size brush triggers and clip brushes */ + NULL, /* 8: Hint */ + NULL, /* 9: Skip */ + "wood", /* 10: Wood */ + "metal", /* 11: Metal */ + "stone", /* 12: Stone */ + "glass", /* 13: Glass */ + "ice", /* 14: Ice */ + "snow", /* 15: Snow */ + "mirror", /* 16: Mirror */ + "holy grond", /* 17: Holy Grond */ + NULL, /* 18: Alphachan */ + NULL, /* 19: Midtexture (Used together with Clear and Nodraw.) */ + "puddle", /* 20: Puddle */ + "water surge", /* 21: Water Surge */ + "big water surge", /* 22: Big Water Surge */ + "bullet light", /* 23: Bullet Light */ + "fog", /* 24: Fog */ + "sand", /* 25: Sand */ + NULL, /* 26: Unused */ + NULL, /* 27: Unused */ + NULL, /* 28: Unused */ + NULL, /* 29: Unused */ + NULL, /* 30: Unused */ + NULL, /* 31: Unused */ +}; + static const int daikatana_contents_flags[32] = { CONTENTS_SOLID, /* 0: Default for all brushes */ CONTENTS_WINDOW, /* 1: Brush is a window (not really used) */ @@ -284,6 +322,44 @@ static const int kingpin_flags[32] = { 0, /* 31: Unused */ }; +static const char * kingpin_material[32] = { + NULL, /* 0: Emit light from the surface, brightness is specified + * in the 'value' field */ + NULL, /* 1: The surface is slippery */ + NULL, /* 2: The surface is sky, the texture will not be drawn, + * but the background sky box is used instead */ + NULL, /* 3: The surface warps (like water textures do) */ + NULL, /* 4: The surface is 33% transparent */ + NULL, /* 5: The surface is 66% transparent */ + NULL, /* 6: The texture wraps in a downward 'flowing' pattern + * (warp must also be set) */ + NULL, /* 7: Used for non-fixed-size brush triggers and clip brushes */ + NULL, /* 8: Make a primary bsp splitter */ + NULL, /* 9: Skip, Completely ignore, allowing non-closed brushes */ + NULL, /* 10: Specular */ + NULL, /* 11: Diffuse */ + NULL, /* 12: Alpha texture */ + NULL, /* 13: Mirror */ + NULL, /* 14: Wndw33 */ + NULL, /* 15: Wndw66 */ + NULL, /* 16: Unused */ + NULL, /* 17: Unused */ + NULL, /* 18: Unused */ + "water", /* 19: Water sound */ + "concrete", /* 20: Concrete sound */ + "fabric", /* 21: Fabric sound */ + "gravel", /* 22: Gravel sound */ + "metal", /* 23: Metal sound */ + "metal light", /* 24: Metal light sound */ + "tin", /* 25: Tin sound */ + "tile", /* 26: Tile sound */ + "wood", /* 27: Wood sound */ + NULL, /* 28: Reflect fake */ + NULL, /* 29: Reflect light */ + NULL, /* 30: Unused */ + NULL, /* 31: Unused */ +}; + static const int kingpin_contents_flags[32] = { CONTENTS_SOLID, /* 0: An eye is never valid in a solid */ CONTENTS_WINDOW, /* 1: translucent, but not watery */ diff --git a/src/common/maps.c b/src/common/maps.c index 5314a8e55..a29d88e4f 100644 --- a/src/common/maps.c +++ b/src/common/maps.c @@ -75,6 +75,78 @@ Mod_LoadSurfConvertFlags(int flags, maptype_t maptype) return Mod_LoadConvertFlags(flags, convert); } +/* + * Convert other games flags to Quake 2 material name + */ +static void +Mod_LoadMaterialConvertFlags(int flags, maptype_t maptype, char *value) +{ + const char **material = NULL; + int i; + + if (maptype == map_heretic2) + { + const char *surface_materials[] = { + "gravel", + "metal", + "stone", + "wood", + }; + + flags = (flags >> 24) & 0x3; + + strcpy(value, surface_materials[flags]); + return; + } + else if (maptype == map_sin) + { + const char *surface_materials[] = { + "", + "wood", + "metal", + "stone", + "concrete", + "dirt", + "flesh", + "grill", + "glass", + "fabric", + "monitor", + "gravel", + "vegetation", + "paper", + "dust", + "water", + }; + + flags = (flags >> 27) & 0xf; + + strcpy(value, surface_materials[flags]); + return; + } + + switch (maptype) + { + case map_daikatana: material = daikatana_material; break; + case map_kingpin: material = kingpin_material; break; + default: break; + } + + if (!material) + { + return; + } + + for (i = 0; i < 32; i++) + { + if (flags & (1 << i) && material[i]) + { + strcpy(value, material[i]); + return; + } + } +} + /* * Convert other games flags to Quake 2 context flags */ @@ -265,7 +337,7 @@ Mod_Load2QBSP_MATERIALS_TEXINFO(xtexinfo_t *out, int count) { if (out->texture[0]) { - char material_path[70]; + char material_path[80]; byte *raw; int len; @@ -304,7 +376,7 @@ Mod_Load2QBSP_IBSP_TEXINFO(byte *outbuf, dheader_t *outheader, for (i = 0; i < count; i++) { - int j; + int j, inflags; for (j = 0; j < 4; j++) { @@ -312,9 +384,11 @@ Mod_Load2QBSP_IBSP_TEXINFO(byte *outbuf, dheader_t *outheader, out->vecs[1][j] = LittleFloat(in->vecs[1][j]); } - out->flags = Mod_LoadSurfConvertFlags(LittleLong(in->flags), maptype); + inflags = LittleLong(in->flags); + out->flags = Mod_LoadSurfConvertFlags(inflags, maptype); out->nexttexinfo = LittleLong(in->nexttexinfo); memset(out->material, 0, sizeof(out->material)); + Mod_LoadMaterialConvertFlags(inflags, maptype, out->material); strncpy(out->texture, in->texture, Q_min(sizeof(out->texture), sizeof(in->texture))); @@ -344,7 +418,7 @@ Mod_Load2QBSP_RBSP_TEXINFO(byte *outbuf, dheader_t *outheader, for (i = 0; i < count; i++) { - int j; + int j, inflags; for (j = 0; j < 4; j++) { @@ -352,9 +426,11 @@ Mod_Load2QBSP_RBSP_TEXINFO(byte *outbuf, dheader_t *outheader, out->vecs[1][j] = LittleFloat(in->vecs[1][j]); } - out->flags = Mod_LoadSurfConvertFlags(LittleLong(in->flags), maptype); + inflags = LittleLong(in->flags); + out->flags = Mod_LoadSurfConvertFlags(inflags, maptype); out->nexttexinfo = LittleLong(in->nexttexinfo); memset(out->material, 0, sizeof(out->material)); + Mod_LoadMaterialConvertFlags(inflags, maptype, out->material); strncpy(out->texture, in->texture, Q_min(sizeof(out->texture), sizeof(in->texture)));