Initial commit

This commit is contained in:
Jarrod Doyle 2024-07-14 16:33:00 +01:00
commit 650aee9015
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
47 changed files with 1117 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/test_data

BIN
DarkFormat.hexproj Normal file

Binary file not shown.

6
patterns/Common.hexpat Normal file
View File

@ -0,0 +1,6 @@
#pragma once
struct Table<T> {
s32 size;
T data;
};

100
patterns/CowFile.hexpat Normal file
View File

@ -0,0 +1,100 @@
#include <std/string.pat>
#include <std/io.pat>
#include "FileBase.hexpat"
#include "lgtypes.hexpat"
#include "chunks/AI_ROOM_DB.hexpat"
#include "chunks/AIACS.hexpat"
#include "chunks/AICONVERSE.hexpat"
#include "chunks/AICRTSZ.hexpat"
#include "chunks/AIGPTHVAR.hexpat"
#include "chunks/AIHearStat.hexpat"
#include "chunks/AIPATHVAR.hexpat"
#include "chunks/AISNDTWK.hexpat"
#include "chunks/AMBIENT.hexpat"
#include "chunks/BASH.hexpat"
#include "chunks/BRHEAD.hexpat"
#include "chunks/BRLIST.hexpat"
#include "chunks/BRVER.hexpat"
#include "chunks/CELL_MOTION.hexpat"
#include "chunks/CELOBJVAR.hexpat"
#include "chunks/CLOUDOBJVAR.hexpat"
#include "chunks/DARKCOMBAT.hexpat"
#include "chunks/DARKMISS.hexpat"
#include "chunks/DISTOBJVAR.hexpat"
#include "chunks/DRKSET.hexpat"
#include "chunks/ENVMAPVAR.hexpat"
#include "chunks/FAMILY.hexpat"
#include "chunks/FILE_TYPE.hexpat"
#include "chunks/FLOW_TEX.hexpat"
#include "chunks/FOGZONEVAR.hexpat"
#include "chunks/MAPISRC.hexpat"
#include "chunks/Mission_GameSysEAX.hexpat"
#include "chunks/RENDPARAMS.hexpat"
#include "chunks/ROOM_DB.hexpat"
#include "chunks/ROOM_EAX.hexpat"
#include "chunks/ScrModules.hexpat"
#include "chunks/SKYMODE.hexpat"
#include "chunks/SKYOBJVAR.hexpat"
#include "chunks/SONGPARAMS.hexpat"
#include "chunks/STAROBJVAR.hexpat"
#include "chunks/TILIST.hexpat"
#include "chunks/TXLIST.hexpat"
#include "chunks/TXTPAT_DB.hexpat"
#include "chunks/WATERBANKS.hexpat"
#include "chunks/WEATHERVAR.hexpat"
#include "chunks/WREXT.hexpat"
FileHeader file_header @ 0x0;
TableOfContents toc @ file_header.toc_offset;
TOCEntry brlist_toc = get_toc_entry(toc, "BRLIST");
TOCEntry scrmodules_toc = get_toc_entry(toc, "ScrModules");
Chunk<AiRoomDb::ChunkData> ai_room_db @ get_offset(toc, "AI_ROOM_DB");
Chunk<AiAcuitySets> ai_acuity_sets @ get_offset(toc, "AIACS");
Chunk<AiConverse> ai_conversations @ get_offset(toc, "AICONVERSE");
Chunk<AiCreatureSizes> ai_creature_sizes @ get_offset(toc, "AICRTSZ");
Chunk<AiGamesysPathOptions> ai_gamesys_path_options @ get_offset(toc, "AIGPTHVAR");
Chunk<AiHearStat> ai_hear_stat @ get_offset(toc, "AIHearStat");
Chunk<AiPathVar> ai_path_var @ get_offset(toc, "AIPATHVAR");
Chunk<AiSndTwk> ai_sound_tweaks @ get_offset(toc, "AISNDTWK");
Chunk<Ambient> ambient @ get_offset(toc, "AMBIENT");
Chunk<Bash> bash @ get_offset(toc, "BASH");
Chunk<BrHead> br_head @ get_offset(toc, "BRHEAD");
Chunk<BrList> br_list @ get_offset(toc, "BRLIST");
Chunk<BrushVersion> brush_version @ get_offset(toc, "BRVER");
Chunk<CellMotion> cell_motion @ get_offset(toc, "CELL_MOTION");
Chunk<CelObjVar> celestial_object_var_1 @ get_offset(toc, "CELOBJVAR1");
Chunk<CelObjVar> celestial_object_var_2 @ get_offset(toc, "CELOBJVAR2");
Chunk<CelObjVar> celestial_object_var_3 @ get_offset(toc, "CELOBJVAR3");
Chunk<CloudObjVar> cloud_object_var @ get_offset(toc, "CLOUDOBJVAR");
Chunk<DarkCombat> dark_combat @ get_offset(toc, "DARKCOMBAT");
Chunk<DarkMiss> dark_miss @ get_offset(toc, "DARKMISS");
Chunk<DistantArtVar> distant_art_var @ get_offset(toc, "DISTOBJVAR");
Chunk<DarkSettings> dark_settings @ get_offset(toc, "DRKSET");
Chunk<EnvMapVar> env_map_var @ get_offset(toc, "ENVMAPVAR");
Chunk<Family> family @ get_offset(toc, "FAMILY");
Chunk<FileType> file_type @ get_offset(toc, "FILE_TYPE");
Chunk<FlowTex> flow_tex @ get_offset(toc, "FLOW_TEX");
Chunk<FogZoneVar> fog_zone_var @ get_offset(toc, "FOGZONEVAR");
Chunk<AccousticsProperty> gamesys_eax @ get_offset(toc, "GameSysEAX");
Chunk<NameNum> hot_regions @ get_offset(toc, "HotRegions");
Chunk<MapISrc> map_i_src @ get_offset(toc, "MAPISRC");
Chunk<AccousticsProperty> mission_eax @ get_offset(toc, "MissionEAX");
Chunk<NameNum> multibrush @ get_offset(toc, "MultiBrush");
Chunk<RendParams> rend_params @ get_offset(toc, "RENDPARAMS");
Chunk<RoomDb> room_db @ get_offset(toc, "ROOM_DB");
Chunk<RoomEax> room_eax @ get_offset(toc, "ROOM_EAX");
Chunk<ScrModules::ChunkData> script_modules @ get_offset(toc, "ScrModules");
Chunk<SkyMode> sky_mode @ get_offset(toc, "SKYMODE");
Chunk<SkyObjVar> sky_object_var @ get_offset(toc, "SKYOBJVAR");
Chunk<MissionSongParams> mision_song_params @ get_offset(toc, "SONGPARAMS");
Chunk<StarObjVar> star_object_var @ get_offset(toc, "STAROBJVAR");
Chunk<TiList> ti_list @ get_offset(toc, "TILIST");
Chunk<TxList> texture_list @ get_offset(toc, "TXLIST");
Chunk<TexturePatchDatabase> texture_patch_database @ get_offset(toc, "TXTPAT_DB");
Chunk<WaterBanks> water_banks @ get_offset(toc, "WATERBANKS");
Chunk<WeatherVar> weather_var @ get_offset(toc, "WEATHERVAR");
Chunk<WrExt> world_rep @ get_offset(toc, "WREXT");

50
patterns/FileBase.hexpat Normal file
View File

@ -0,0 +1,50 @@
#pragma once
using TOCEntry;
struct Version {
u32 major;
u32 minor;
};
struct FileHeader {
u32 toc_offset;
Version version;
padding[256];
u32 deadbeef;
};
struct TableOfContents {
u32 item_count;
TOCEntry items[item_count];
};
struct TOCEntry {
char name[12];
u32 offset;
u32 size;
};
struct ChunkHeader {
char name[12];
Version version;
padding[4];
};
struct Chunk<T> {
ChunkHeader header;
T data;
};
fn get_toc_entry(TableOfContents toc, str entry_name) {
for (u32 i = 0, i < toc.item_count, i = i + 1) {
if (std::string::starts_with(toc.items[i].name, entry_name)) {
return toc.items[i];
}
}
};
fn get_offset(TableOfContents toc, str entry_name) {
TOCEntry entry = get_toc_entry(toc, entry_name);
return entry.offset;
};

View File

@ -0,0 +1,16 @@
#pragma once
struct AcuitySet {
float lighting;
float movement;
float exposure;
};
struct AiAcuitySets {
AcuitySet normal;
AcuitySet peripheral;
AcuitySet omni;
AcuitySet light_only;
AcuitySet movement_only;
AcuitySet low_light;
};

View File

@ -0,0 +1,6 @@
#pragma once
struct AiConverse {
u32 count;
u32 ids[count];
};

View File

@ -0,0 +1,10 @@
#pragma once
struct AiCreatureSize {
float width;
float height;
};
struct AiCreatureSizes {
AiCreatureSize sizes[8];
};

View File

@ -0,0 +1,5 @@
#pragma once
struct AiGamesysPathOptions {
float large_door_size;
};

View File

@ -0,0 +1,6 @@
#pragma once
struct AiHearStat {
float distance_multipliers[6];
s32 decibel_additions[6];
};

View File

@ -0,0 +1,5 @@
#pragma once
struct AiPathVar {
s32 pathable_water;
};

View File

@ -0,0 +1,10 @@
#pragma once
struct AiSndTwk {
s32 default_untyped_range;
s32 default_inform_range;
s32 default_minor_anomoly_range;
s32 default_major_anomoly_range;
s32 default_non_combat_high_range;
s32 default_combat_range;
};

View File

@ -0,0 +1,50 @@
#pragma once
#include "Common.hexpat"
#include "lgtypes.hexpat"
namespace AiRoomDb {
struct Cell {
s32 size;
u32 cell_ids[size];
};
struct PathEdge {
u32 cell;
u32 vertex_a;
u32 vertex_b;
};
struct Path {
s32 path_version;
Vec3<float> final_destination; // unsure about this type
s32 current_edge;
bool active;
padding[3];
s32 size;
PathEdge edges[size];
};
struct PortalPath {
u64 cost;
bool has_path;
padding[3];
if (has_path) {
Path path;
}
};
struct ChunkData {
bool database_empty;
padding[3];
s32 valid_cell_count;
s32 cell_count;
Cell cells[cell_count];
// Seems like ROOM_PATHS isn't defined :)
if (0) {
Table<Table<Table<PortalPath>>> portal_ai_paths;
s32 portal_hint_count;
s32 portal_hints[portal_hint_count];
}
};
}

View File

@ -0,0 +1,5 @@
#pragma once
struct Ambient {
s32 current_env_idx;
};

View File

@ -0,0 +1,6 @@
#pragma once
struct Bash {
float threshold;
float coefficient;
};

View File

@ -0,0 +1,16 @@
#pragma once
struct BrHead {
char user[16];
char creator[16];
char fullname[64]; // I don't think this is actually ever used
s32 ambient;
s32 grid_pow2;
s32 brush_pos;
s32 color_state;
s32 vbrush_info;
bool use_grid;
bool hots_state;
padding[2];
s32 edit_time; // Milliseconds
};

View File

@ -0,0 +1,91 @@
#pragma once
#include "lgtypes.hexpat"
using Br;
using Grid;
using TexInfo;
using BrMedia;
using BrType;
struct BrList {
Br brushes[while($ < brlist_toc.offset + brlist_toc.size)];
};
// Potentially rename fields depending on the media type?
struct Br {
s16 br_id;
s16 timestamp;
BrType primal_id;
s16 tx_id;
BrMedia media;
s8 flags; // potential bitfield
Vec3<float> pos; // Brush center
Vec3<float> sz; // Brush extents (dimensions)
Vec3<u16> ang;
s16 cur_face;
Grid grid;
u8 num_faces;
s8 edge;
s8 point;
s8 use_flg;
s8 group_id;
padding[4];
// We have to do a double cast here because otherwise the s8 for non-terrain brushes is just wrong??
if (s8(u8(media)) >= 0) {
TexInfo txs[num_faces];
}
};
struct Grid {
float line_spacing;
Vec3<float> phase_shift;
Vec3<u16> orientation;
bool grid_enabled;
};
struct TexInfo {
s16 id;
u16 rot;
s16 scale;
u16 x;
u16 y;
};
enum BrMedia : s8 {
Room = 0xFB,
Flow = 0xFC,
Object = 0xFD,
Area = 0xFE,
Light = 0xFF,
FillSolid = 0x00,
FillAir = 0x01,
FillWater = 0x02,
Flood = 0x03,
Evaporate = 0x04,
SolidToWater = 0x05,
SolidToAir = 0x06,
AirToSolid = 0x07,
WaterToSolid = 0x08,
Blockable = 0x09,
};
enum BrPrimType : u8 {
Special = 0x0,
Cylinder = 0x1,
Pyramid = 0x2,
CornerPyr = 0x3,
};
enum BrAligned : u8 {
Vertex = 0x0,
Side = 0x1,
};
// If we're a "special" brush side_info says what type we are, otherwise it's
// side count - 3
bitfield BrType {
side_info: 8;
side_aligned: 1;
BrPrimType prim_type: 23;
};

View File

@ -0,0 +1,5 @@
#pragma once
struct BrushVersion {
s32 version;
};

View File

@ -0,0 +1,24 @@
#pragma once
#include "lgtypes.hexpat"
struct CellMotionPortal {
Vec3<float> center;
u16 angle;
bool in_motion;
padding[3];
u8 major_axis;
padding[2];
};
struct CellMotionMedium {
Vec3<float> center;
u16 angle_change;
};
struct CellMotion {
CellMotionPortal portal_motions[256];
CellMotionMedium medium_motions[256];
s32 unknown;
};

View File

@ -0,0 +1,18 @@
#pragma once
struct CelObjVar {
bool enable_object;
padding[3];
bool enable_fog;
padding[3];
bool is_alpha_texture;
padding[3];
char texture[256];
float alpha;
float celestial_offset;
float angular_size;
float latitude;
float longitude;
float rotation;
Vec3<float> color;
};

View File

@ -0,0 +1,37 @@
#pragma once
#include "lgtypes.hexpat"
using ColorSettings;
struct CloudObjVar {
bool enable_cloud_deck;
padding[3];
bool enable_fog;
padding[3];
bool is_alpha_texture;
padding[3];
char texture_path[256];
float alpha;
float height;
float tile_size;
s32 num_tiles_per_side;
s32 num_sub_tiles;
Vec3<float> wind_velocity;
Vec3<float> overall_color;
ColorSettings east;
ColorSettings west;
float east_west_rotation;
s32 sub_tile_alpha_start;
ColorSettings glow;
float glow_latitude;
float glow_longitude;
float glow_angle;
s32 glow_tiles;
};
struct ColorSettings {
Vec3<float> color;
ColorMethod color_method;
float scale;
};

View File

@ -0,0 +1,6 @@
#pragma once
struct DarkCombat {
s32 backstab_bonus;
float in_combat_min_distance;
};

View File

@ -0,0 +1,6 @@
#pragma once
struct DarkMiss {
s32 num;
char path[9];
};

View File

@ -0,0 +1,17 @@
#pragma once
struct DistantArtVar {
bool enable_distant_art;
padding[3];
bool enable_fog;
padding[3];
char texture_1[256];
char texture_2[256];
Vec3<float> color;
float distance;
float top_latitude;
float bottom_latitude;
s32 num_panels;
s32 num_texture_panels;
float alpha;
};

View File

@ -0,0 +1,7 @@
#pragma once
struct DarkSettings {
bool custom_metaprop_action_targets;
padding[3];
padding[28];
};

View File

@ -0,0 +1,11 @@
#pragma once
struct EnvMap {
char path[64];
};
struct EnvMapVar {
padding[4];
EnvMap global;
EnvMap regions[64];
};

View File

@ -0,0 +1,11 @@
#pragma once
struct FamilyName {
char name[parent.name_len];
};
struct Family {
u32 name_len;
u32 count;
FamilyName names[count];
};

View File

@ -0,0 +1,19 @@
#pragma once
bitfield FileTypeFlags {
padding: 8;
ObjPartConcrete: 1;
ObjPartAbstract: 1;
ObjPartBriefcase: 1;
ObjPartTerrain: 1;
ObjPartMission: 1;
padding: 3;
Mission: 1;
Map: 1;
GameSys: 1;
padding: 13;
};
struct FileType {
FileTypeFlags file_type;
};

View File

@ -0,0 +1,12 @@
#pragma once
struct MotionSurface {
s16 texture_above;
s16 texture_below;
char texture_name_base[16];
padding[12];
};
struct FlowTex {
MotionSurface motion_surfaces[256];
};

View File

@ -0,0 +1,14 @@
#pragma once
#include "lgtypes.hexpat"
struct FogZone {
padding[1];
Vec3<u8> color;
float dist;
};
struct FogZoneVar {
FogZone global;
FogZone regional[8];
};

View File

@ -0,0 +1,6 @@
#pragma once
struct MapISrc {
s32 source_miss;
float compass_diff;
};

View File

@ -0,0 +1,7 @@
#pragma once
struct AccousticsProperty {
s32 reverb;
s32 dampening;
s32 height;
};

View File

@ -0,0 +1,27 @@
#pragma once
#include "lgtypes.hexpat"
enum SunlightMode : s32 {
SingleUnshadowed = 0x0,
QuadObjcastShadows = 0x1,
QuadUnshadowed = 0x2,
SingleObjcastShadows = 0x3,
};
struct RendParams {
char palette_res[16];
Vec3<float> ambient_light;
s32 sunlight;
SunlightMode sunlight_mode;
Vec3<float> sunlight_direction;
float sunlight_hue;
float sunlight_saturation;
float sunlight_brightness;
padding[24];
float view_distance;
padding[12];
Vec3<float> ambient_light_zones[8];
float global_ai_vis_bias;
float ambient_zone_ai_vis_biases[8];
};

View File

@ -0,0 +1,45 @@
#pragma once
#include "lgtypes.hexpat"
struct RoomPortal {
s32 id;
s32 index;
Plane plane;
s32 edge_plane_count;
Plane edge_planes[edge_plane_count];
s32 far_room_id;
s32 near_room_id;
Vec3<float> center;
s32 far_portal_id;
};
struct WatchListItem {
s32 count;
s32 watch_values[count];
};
struct PortalDistancesCol {
float distances[parent.portal_count];
};
struct Room {
s32 object_id;
s16 room_id;
Vec3<float> center;
Plane planes[6];
s32 portal_count;
RoomPortal portals[portal_count];
PortalDistancesCol portal_distances[portal_count];
s32 watch_list_size;
WatchListItem watch_list[watch_list_size];
};
struct RoomDb {
bool has_rooms;
padding[3];
if (has_rooms) {
s32 count;
Room rooms[count];
}
};

View File

@ -0,0 +1,6 @@
#pragma once
struct RoomEax {
s32 count;
s32 indices[count];
};

View File

@ -0,0 +1,10 @@
#pragma once
enum SkyRenderingMode : s32 {
Textures = 0x0,
Stars = 0x1,
};
struct SkyMode {
SkyRenderingMode mode;
};

View File

@ -0,0 +1,27 @@
#pragma once
#include "lgtypes.hexpat"
struct SkyObjVar {
bool enable_new_sky;
padding[3];
bool enable_fog;
padding[3];
float atmosphere_radius;
float earth_radius;
s32 num_latitude_points;
s32 num_longitude_points;
float horizon_dip_angle;
Vec3<float> pole_color;
Vec3<float> degree_45_color;
Vec3<float> degree_70_color;
Vec3<float> horizon_color;
Vec3<float> horizon_dip_color;
Vec3<float> glow_color;
float glow_latitude;
float glow_longitude;
float glow_angle;
float glow_scale;
ColorMethod glow_method;
float clip_latitude;
};

View File

@ -0,0 +1,5 @@
#pragma once
struct MissionSongParams {
char song_name[32];
};

View File

@ -0,0 +1,12 @@
#pragma once
struct StarObjVar {
bool enable_stars;
padding[3];
bool enable_fog;
padding[3];
float density;
float star_offset;
float max_intensity;
float global_transparency;
};

View File

@ -0,0 +1,14 @@
#pragma once
#include <std/io.pat>
namespace ScrModules {
struct Name {
char name[128];
};
struct ChunkData {
Name names[while($ < scrmodules_toc.offset + scrmodules_toc.size)];
};
}

View File

@ -0,0 +1,23 @@
#pragma once
enum TiAlignmentMode : s32 {
AlignNorm = 0x0,
AlignBr = 0x1,
AlignExt = 0x2,
};
struct TiScale {
s16 fractional; // decimal = fractional / 2^16
s16 integer;
};
struct TiItem {
TiAlignmentMode p1;
TiScale scale_x;
TiScale scale_y;
};
struct TiList {
s32 count;
TiItem items[count];
};

View File

@ -0,0 +1,19 @@
#pragma once
struct TextureListToken {
char name[16];
};
struct TextureListData {
char tokens[4];
char name[15];
char reserved;
};
struct TxList {
s32 block_size;
s32 count;
s32 token_count;
TextureListToken tokens[token_count];
TextureListData data[count];
};

View File

@ -0,0 +1,11 @@
#pragma once
struct TexturePatch {
s32 key;
s32 value;
};
struct TexturePatchDatabase {
s32 count;
TexturePatch patches[count];
};

View File

@ -0,0 +1,11 @@
#pragma once
struct RGBA {
Vec3<u8> rgb;
padding[1];
float a;
};
struct WaterBanks {
RGBA banks[4];
};

View File

@ -0,0 +1,24 @@
#pragma once
enum Precipitation : u32 {
Snow = 0x0,
Rain = 0x1,
};
struct WeatherVar {
Precipitation precipitation;
float frequency;
float fall_speed;
float visible_distance;
float render_radius;
float alpha;
float brightness;
float snow_jitter;
float rain_length;
float splash_requency;
float splash_radius;
float splash_height;
float splash_duration;
char texture[32];
Vec3<float> wind;
};

View File

@ -0,0 +1,245 @@
#pragma once
#include <std/bit.pat>
#include <std/math.pat>
#include <std/core.pat>
#include <std/io.pat>
#include "FileBase.hexpat"
using WrHeader;
using WrCell;
using WrCellHeader;
using WrPoly;
using WrRenderPoly;
using WrPlane;
using WrLightMapInfo;
using WrLightMap;
using WrLightMapLayer;
using WrLightMapDataPixel;
using WrBspTree;
using WrBspTreeNode;
using WrBspTreeCellPlane;
using WrLightTable;
using WrLightTableData;
using WrLightTableAnimLight;
using WrCsgCellTable;
using WrCsgCellBrFaceTable;
using WrCsgCellBspPlaneTable;
using WrCsgCellRefTable;
using WrCsgCellSurfaceRef;
struct WrExt {
WrHeader header;
WrCell cells[header.cell_count];
WrBspTree bsp_tree;
padding[header.cell_count]; // This is suspicious. Fog? SEE VFIGS MISSDEEDS!!
WrLightTable lights;
WrCsgCellTable csg_cell_table;
};
struct WrExtHeader {
s32 size;
s32 version;
s32 flags; // Need to bitmask this
u32 lightmap_format;
s32 lightmap_scale;
};
struct WrHeader {
WrExtHeader ext_header;
u32 data_size;
u32 cell_count;
u32 major = parent.parent.header.version.major;
u32 minor = parent.parent.header.version.minor;
u32 bytes_per_pixel = 0;
if (major == 0 && minor == 23) {
bytes_per_pixel = 1;
} else if (major == 0 && minor == 24) {
bytes_per_pixel = 2;
} else if (major == 0 && minor == 30) {
if (ext_header.lightmap_format == 0) {
bytes_per_pixel = 2;
} else {
bytes_per_pixel = 4;
}
}
};
struct WrCell {
WrCellHeader header;
Vec3<float> p_vertices[header.vertex_count];
WrPoly p_polys[header.poly_count];
WrRenderPoly p_render_polys[header.render_poly_count];
u32 index_count;
u8 p_index_list[index_count];
WrPlane p_plane_list[header.plane_count];
u16 p_anim_lights[header.anim_light_count];
WrLightMapInfo p_light_list[header.render_poly_count];
WrLightMap lightmaps[header.render_poly_count];
s32 light_index_count;
u16 p_light_indices[light_index_count];
};
struct WrCellHeader {
u8 vertex_count;
u8 poly_count;
u8 render_poly_count;
u8 portal_poly_count;
u8 plane_count;
u8 medium;
u8 flags;
s32 portal_vertex_list;
u16 num_v_list;
u8 anim_light_count;
u8 motion_index;
Vec3<float> sphere_center;
float sphere_radius;
};
struct WrPoly {
u8 flags;
u8 vertex_count;
u8 plane_id;
u8 clut_id;
u16 destination;
u8 motion_index;
padding[1];
};
struct WrRenderPoly {
Vec3<float> tex_u;
Vec3<float> tex_v;
float base_u;
float base_v;
u16 texture_id;
u16 cached_surface;
float texture_mag;
Vec3<float> center;
};
struct WrPlane {
Vec3<float> normal;
float distance;
};
// TODO: Right now we're assuming a certain LM format because I don't know how to pass
// that info from the WrHeader :)
struct WrLightMapInfo {
s16 base_u;
s16 base_v;
s16 padded_width;
u8 height;
u8 width;
u32 data_ptr;
u32 dynamic_light_ptr;
u32 anim_light_bitmask;
};
struct WrLightMap {
s32 i = std::core::array_index();
// There seems to be an ImHex bug to work around here. Doing this sets every member of the struct
// to the first value. Accessing it directly rather than using a local variable works.
//WrLightMapInfo info = parent.p_light_list[i];
u8 width = parent.p_light_list[i].width;
u8 height = parent.p_light_list[i].height;
u32 count = 1 + std::bit::popcount(parent.p_light_list[i].anim_light_bitmask);
u32 bytes_per_pixel = parent.parent.header.bytes_per_pixel;
WrLightMapLayer layers[count];
};
struct WrLightMapLayer {
WrLightMapDataPixel data[parent.width * parent.height];
};
struct WrLightMapDataPixel {
u8 bytes[parent.parent.bytes_per_pixel];
};
struct WrBspTree {
u32 plane_list_count;
Plane plane_list[plane_list_count];
u32 bsp_tree_size;
WrBspTreeNode bsp_tree[bsp_tree_size];
};
struct WrBspTreeNode {
s24 parent_index;
u8 flags;
WrBspTreeCellPlane cellplane;
u32 inside_index;
u32 outside_index;
};
struct WrBspTreeCellPlane {
s32 cell_id;
s32 plane_id;
};
struct WrLightTable {
s32 light_count;
s32 dynamic_light_count;
// Newdark doesn't pad out with non-used lights!!
//WrLightTableData light_data[768]; // Looks like 2016 in newdark?
//WrLightTableData light_this[32];
WrLightTableData lights[light_count + dynamic_light_count];
WrLightTableData scratchpad_lights[32];
s32 anim_light_count;
WrLightTableAnimLight anim_lights[anim_light_count];
};
struct WrLightTableData {
Vec3<float> location;
Vec3<float> direction;
Vec3<float> colour; // only vec3 in wrrgb and wrext
float inner;
float outer;
float radius;
};
struct WrLightTableAnimLight {
u16 cell_index;
u8 pos_in_palette;
padding[1];
};
// TODO: My actual understanding of this is basically none :)
struct WrCsgCellTable {
s32 cell_count;
WrCsgCellBrFaceTable br_faces[cell_count];
s32 num_brushes;
s32 num_brush_faces[num_brushes];
WrCsgCellBspPlaneTable bsp_planes[num_brushes];
s32 ref_counts[num_brushes];
WrCsgCellRefTable refs[num_brushes];
};
struct WrCsgCellBrFaceTable {
s32 i = std::core::array_index();
s32 face_ptr[parent.parent.cells[i].header.render_poly_count];
};
struct WrCsgCellBspPlaneTable {
s32 i = std::core::array_index();
DPlane planes[parent.num_brush_faces[i]];
};
struct WrCsgCellRefTable {
s32 i = std::core::array_index();
if (parent.ref_counts[i] > 0) {
WrCsgCellSurfaceRef refs[parent.ref_counts[i]];
}
};
struct WrCsgCellSurfaceRef {
s32 cell;
u8 surface;
u8 brush_face;
s16 vertex;
};

55
patterns/lgtypes.hexpat Normal file
View File

@ -0,0 +1,55 @@
#pragma once
using Vec3;
using NameNum;
using NameNumTag;
struct Plane {
float x;
float y;
float z;
float d;
};
struct DPlane {
double x;
double y;
double z;
double d;
};
struct Vec3<T> {
T x;
T y;
T z;
};
struct Vec4<T> {
T x;
T y;
T z;
T w;
};
struct NameNum {
// This header section is actually a tag too, but for namings sake I'll leave it like this
s32 max_names;
s32 sys_name_len;
char sys_name[sys_name_len];
NameNumTag tags[max_names];
};
struct NameNumTag {
s32 value;
if (value != -1) {
s32 name_len;
if (name_len != -1) {
char name[name_len];
}
}
};
enum ColorMethod : s32 {
Sum = 0x0,
Interpolate = 0x1,
};