Files
arcattackandClaude Opus 4.8 7b7d465e5e Initial commit: bt411 -- standalone Windows BattleTech (Tesla 4.10 port)
Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.

Layout:
  engine/   MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
            work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
            models) + image codec; the minimal rp/ headers the audio HAL needs
  game/     reconstructed BT logic + surviving-original BT source + fwd shims
            + WinMain launcher
  content/  full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
  docs/     format specs + reconstruction ledgers
  reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
  tools/    MP console emulator + map/resource scanners

One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 21:03:40 -05:00

532 lines
12 KiB
C++

#ifndef dpltyp_h
#define dpltyp_h
#ifdef __cplusplus
extern "C" {
#endif
/* **************************************************
Copyright DIVISION Limited (c) 1994
All rights reserved
File : dpltypes.h
Project : dpl interface
Author : PJA
Date : 18/6/94
Function: Flesh out all the datatypes
History : Rev 1.0, 18 / 06 / 1994
1.1, 22 / 06 / 1994 fixed unimplementable lists by
introducing dpl_superlist
1.2, 27 / 06 / 1994 dislocated heirarchy from instances
and dropped back to matrix-only DCS
2.0 16 / 11 / 1994 angusification started
**************************** */
#include <dsys/divtypes.h>
#include <dpl/dpltypes.h>
#define OFF_SITE 1
#ifdef i860
#define REMOTE 1
#endif
#define dpl_arg_sep '~'
#define dcs_node_enable 0x1
#define dcs_subtree_enable 0x2
#define dcs_no_view_concat 0x4
#define dcs_billboard_x 0x8
#define dcs_billboard_y 0x10
#define dcs_billboard_z 0x20
#define dcs_explode_geo 0x40
#define dcs_ignore_geo 0x80
#define dcs_inherit_lmodel 0x100
#define dcs_force_eval_lmodel 0x200
#define dcs_near_field 0x400
#define dcs_bounded 0x800
#define dcs_backwards 0x1000
#define dcs_uniform_scale 0x2000
#define dpl_draw_faceted 0x0000
#define dpl_draw_smooth 0x0001
#define dpl_draw_colored 0x0002
#define dpl_draw_luminance 0x0004
#define dpl_draw_textured 0x0008
#define dpl_draw_3dtextured 0x0010
#define dpl_draw_front 0x0200
#define dpl_draw_back 0x0400
#define dpl_draw_edges 0x0800
#define dpl_draw_wireframe 0x1000
#define dpl_draw_last 0x2000
#define dpl_draw_envmapped 0x4000
#define dpl_draw_flipped 0x8000
#define dpl_draw_f_emissive 0x0020
#define dpl_draw_b_emissive 0x0040
#define dpl_X 0
#define dpl_Y 1
#define dpl_Z 2
#define dpl_W 3
#ifdef _DOS
#define dpl_path_separator '\\'
#else
#define dpl_path_separator '/'
#endif
/*
NOTE in rpc implementations, the rather large overhead
of the dpl_node dplnode is never passed over to the
remote renderer, its just in the host space for management
*/
typedef struct s_dplnode* (*node_create_function)( void );
typedef struct s_dplnode {
int32 clean;
void *app_specific;
void *remote; /* this MUST be 1st word of REMOTE data */
dpl_TYPE type_check;
} dpl_node;
typedef struct s_dplremote_node {
void *remote;
dpl_TYPE type_check;
} dpl_remote_node;
#ifdef REMOTE
#define dpl_node dpl_remote_node
#endif
typedef struct s_dpl_chain_node {
dpl_node node;
struct s_dpl_chain_node *next_node;
struct s_dpldcs *dcs;
} dpl_chain_node;
typedef int32 (*load_function)( dpl_node *, char * );
typedef struct s_dpllist {
dpl_node *item;
dpl_TYPE type_check;
struct s_dpllist *next;
struct s_dpllist *prev;
} dpl_list;
/*
the dpl_superlist is used as the head node for
dpl_lists
*/
typedef struct s_dplsuperlist {
dpl_node *dplnode;
dpl_list *last_accessed;
dpl_list *head;
dpl_list *tail;
} dpl_superlist;
typedef float32 dpl_POINT [4];
typedef float32 dpl_MATRIX[4][4];
typedef union {
double dbl_MATRIX[8];
dpl_MATRIX matrix;
} dpl_dblMATRIX;
/* introduce local datatypes */
/*
The renderer is currently blowing off way too much storage on the card,
which stands to sense when each polygon is around 144 bytes, 80 bytes for the
vertex and 64 for the connection structure. The currently unused datatypes
below will eventually attempt to buy back a lot of storage by moving away
from linked lists and towards packed structures
*/
typedef struct s_rvert {
dpl_POINT position; /* 0 */
dpl_POINT normcol; /* 16 */
float32 texcoords [3]; /* 32 */
struct s_rvert *next; /* 44 */
dpl_POINT xform_posn; /* 48 */
float32 rendered_color[3]; /* 64 */
int32 touched; /* 76 */
} dpl_VERTEX;
typedef struct s_conn {
struct s_conn *next; /* 0 */
int32 n_verts; /* 4 */
dpl_VERTEX* indices[6]; /* 8 */
dpl_POINT planeEqn; /* 32 */
float32 rendered_color[3]; /* 48 */
int32 touched; /* 60 */
} dpl_CONNECTION;
/* we will only use this structure for polys, not spheres,
so the W-coordinate (radius) holds the touched word
*/
typedef struct s_ivert {
float32 position[3]; /* 3 */
int32 touched; /* 4 */
dpl_POINT normcol; /* 8 */
float32 texcoords [2]; /* 10 total = 40 bytes */
} dpl_idealVERTEX;
typedef struct s_iconn {
dpl_POINT planeEqn; /* 4 */
dpl_idealVERTEX* indices[6]; /* 10 */
} dpl_idealCONNECTION; /* total 40 bytes */
typedef struct s_oconn {
float planeEqn[3];
int touched;
int indices[6];
} dpl_outputCONNECTION; /* total 40 bytes */
/*
it looks like we can drop polygon storage down to 80 bytes
per poly, rather than 144, so we can achieve around 80% more
database storage
the assumption is that we use connection[3] == NULL as the triangle
spotter. is this iffy? it lets us keep hexes for performance.
planeEqn[3] = touched for output conns, so we have 32 bytes, giving
a 72 byte triangle and _doubling_ storage.
in order to make this work, we will need a single PMESH of worst-case
size hanging round in memory. So xforming and lighting will no longer
happen in-place, but the destination for the work will always be the
same area of memory. So we'll get better cache and page coherence.
It is recommended that we drop PMESH size from 6 to 4.
The VERTEX pointers in the connection structure must now become
byte indices, so we just add on the base address of the VERTEX
structure.
The only problem is special effects - the sphere effects are just dealt
with by keeping spherelists in the old vertex format; triangle effects
may be more difficult to deal with.
*/
/* flesh out the datatypes in dpltypes.h */
#if 0
struct s_dpl_statistics {
float32 polys_in_last_frame;
float32 last_edit_time;
float32 last_cull_time;
float32 last_frame_time;
float32 last_frame_time_sb;
float32 polys_per_second;
float32 polys_per_second_sb;
} dpl_STATISTICS;
#endif
struct s_dpldcs {
dpl_node dplnode;
dpl_chain_node *nodes;
struct s_dplzone *zone;
dpl_MATRIX matrix;
int32 traversal; /* overload billboards in here for compactness */
struct s_dpldcs *parent;
struct s_dpldcs *sibling;
struct s_dpldcs *child;
int32 lighting_mask;
dpl_POINT bounds[2];
#ifdef REMOTE
dpl_dblMATRIX invModel;
float sphere_scale, sphere_big_scale;
#endif
} ;
struct s_dplzone {
dpl_node dplnode;
int32 view_enable;
} ;
struct s_dplview {
dpl_chain_node dplnode;
int32 view_id;
int32 pipe;
float32 x0, y0, x1, y1, zeye;
float32 x_size, y_size;
float32 hither_clip;
float32 yon_clip;
float32 back_color[3];
int32 fog_enable;
float32 fog[5]; /* near, phar, r, g, b */
struct s_dplview *share_view;
void *display_2d;
} ;
struct s_dpllight {
dpl_chain_node dplnode;
dpl_LIGHT_TYPE light_type;
float32 color [3];
float32 radius [2]; /* for radial lights */
float32 umbra [2]; /* for conical lights */
int32 lighting_mask;
#ifdef REMOTE
float32 position[3];
#endif
};
struct s_dpltexture {
dpl_node dplnode;
struct s_dpltexmap *texmap;
int32 minify;
int32 magnify;
int32 alpha;
int32 wrap_u;
int32 wrap_v;
int32 detail;
float32 u0;
float32 v0;
float32 du;
float32 dv;
float32 animate_time;
int32 bitslice;
int32 delta_size;
int32 delta_offs;
};
struct s_dpltexmap {
dpl_node dplnode;
int32 *texels;
int32 u_size;
int32 v_size;
int32 bits_per_texel;
int32 alpha;
#ifdef REMOTE
int32 hwareSize;
int32 hwareOffs;
int32 bilinear;
void *cell;
#endif
};
struct s_dplmtl {
dpl_node dplnode;
struct s_dpltexture *texture;
struct s_dpltexture *environment;
int32 immunity;
struct s_dplramp *ramp;
float32 emissive [3];
float32 ambient [3];
float32 diffuse [3];
float32 opacity [3];
float32 specular [4];
float32 dither;
#ifdef REMOTE
float surf_opacity;
float *specular_table;
int32 pxpl5_cntl_word;
float du, dv;
float alpha_c, alpha_r;
int32 alpha_texture;
int32 cull_frame;
#endif
};
struct s_dplramp {
dpl_node dplnode;
float32 color0 [3];
float32 color1 [3];
int32 cntl_word;
};
struct s_dplinstance {
dpl_chain_node dplnode;
dpl_ISECT_MODE intersectmode;
int32 visibility;
struct s_dplobject *object;
struct s_dpllod *forcelod;
struct s_dplmtl *f_material;
struct s_dplmtl *b_material;
int32 intersect_mask;
int32 wireframe;
#ifdef REMOTE
int32 frame_count;
int32 last_LOD_index;
#endif
};
#define MAX_LODS_PER_OBJECT 16
struct s_dplobject {
dpl_node dplnode;
dpl_superlist lod_list;
dpl_POINT lod_hot_spot;
float32 lod_ranges[MAX_LODS_PER_OBJECT];
float32 lod_fade_range;
int32 invalid_lods;
int32 clone;
#ifdef REMOTE
int32 lod_count;
float32 bounds[2][4];
dpl_POINT sphere_bounds;
#endif
};
struct s_dpllod {
dpl_node dplnode;
float32 bounds[2][4];
struct s_dplobject *parent;
dpl_superlist geogroup_list;
float32 hot_spot[3];
#ifdef REMOTE
dpl_POINT sphere_bounds;
#endif
};
struct s_dplgeogroup {
dpl_node dplnode;
float32 bounds[2][4];
struct s_dpllod *parent;
int32 draw_mode;
dpl_superlist geometry_list;
struct s_dplmtl *f_material;
struct s_dplmtl *b_material;
float32 decal_offs;
int32 lock;
#ifdef REMOTE
dpl_POINT sphere_bounds;
int32 clean;
#endif
};
struct s_dplgeometry {
dpl_node dplnode;
dpl_GEO_TYPE geometry_type;
dpl_VERTEX_TYPE vertex_type;
int32 num_vertices;
struct s_dplgeogroup *parent;
dpl_CONNECTION *connections;
dpl_VERTEX *vertices;
float lineWidth, pointSize;
#ifdef REMOTE
int32 variable_alpha;
int32 n_connections;
int32 n_vertices;
dpl_CONNECTION *connection_tail;
dpl_VERTEX *vertex_tail;
int32 packed;
#endif
};
#if 0
struct s_dpl_status {
int32 ok;
} dpl_STATUS;
#endif
/* ******************************************
BEWARE ! ! ! ! !
FOR REASONS OF STORAGE AND APPLICATIONS EFFICIENCY, THE FOLLOWING
DATA TYPES ARE N O T SUPERSETS OF DPL_NODE
BE CAREFUL DEALING WITH VERTICES
*/
/* typedefs for tracing performance */
typedef struct s_dpl_version {
int32 host;
int32 major_version;
int32 minor_version;
int32 firmware_major_version;
int32 firmware_minor_version;
char detailed[256];
} dpl_VERSION;
/* **********************************************************
a scene contains a list of root-node dcs's, a list of zones
and a list of views
*/
typedef struct s_dplscene {
dpl_node dplnode;
dpl_superlist zone_list;
dpl_superlist view_list;
dpl_superlist dcs_list;
dpl_superlist light_list;
} dpl_SCENE;
typedef enum {
dpl_artic_matrix,
dpl_artic_singleX,
dpl_artic_singleY,
dpl_artic_singleZ,
dpl_artic_quaternion
} dpl_ARTICULATION;
/* additional geometry types - keep small for switch optim */
#define vpx_geo_type_f_t_dam 16
#define vpx_geo_type_sca 17
#define vpx_geo_type_undamage 18
#define vpx_geo_type_f_t_undam 19
#define vpx_geo_type_damage_set 20
#define dpl_morph_vertices 0x1
#define dpl_morph_normals 0x2
#define dpl_morph_texcoords 0x4
#define dpl_morph_colors 0x8
typedef void (*vfptr)();
extern void *
dpl_svtRead(char8 *, int32 bilinear );
extern void *
dpl_bilRead(char8 *);
extern void *
dpl_glmRead(char8 *);
extern void
dpl_explodeTexels ( dpl_TEXMAP *tm,
int32 *dest_texels,
uint8 *src_texels,
int32 n_texels,
int32 start, int32 bilinear );
#define POLY_FBITS 12
#define SPHERE_FBITS 24
#ifdef __cplusplus
}
#endif
#endif