Files
BT411/reference/decomp/bt_l4_btl4mssn.cpp.c
T
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

334 lines
11 KiB
C

// Recovered decompilation of functions attributed to bt_l4/btl4mssn.cpp
// (from BTL4OPT.EXE via embedded assert paths). Pseudocode — reconstruct against the header.
/* ---- @ 004d2c30 ---- */
void __cdecl FUN_004d2c30(int param_1,int param_2)
{
char *pcVar1;
uint *puVar2;
int *piVar3;
char *pcVar4;
int iVar5;
undefined3 extraout_var;
undefined4 *puVar6;
uint uVar7;
undefined3 extraout_var_00;
undefined3 extraout_var_01;
char *pcVar8;
bool bVar9;
int local_a4 [5];
int local_90 [5];
undefined4 local_7c;
int local_78;
float local_74;
int *local_70;
int *local_6c;
int *local_68;
int *local_64;
int *local_60;
int *local_5c;
undefined4 *local_58;
uint *local_54;
uint *local_50;
uint *local_4c;
char *local_48;
char *local_44;
int *local_40;
char *local_3c;
float local_38;
int local_34;
char *local_30;
int *local_2c;
int *local_28;
char *local_24;
char *local_20;
int *local_1c;
char *local_18;
char *local_14;
char *local_10;
char *local_c;
int *local_8;
local_8 = *(int **)(*(int *)(*(int *)(DAT_004efc94 + 0x2c) + 0x14) + 0x1064);
local_8[3] = local_8[3] + 1;
*(undefined4 *)(param_1 + 0x2c) = 0;
local_c = (char *)0x0;
FUN_00404088(param_2,(char *)local_8[2],s_vehicle_0051e5b5,&local_c);
if (local_c == (char *)0x0) {
FUN_004dbb24(&DAT_00524e20,s_Error__vehicle_not_specified__0051e5bd,(char *)0x0);
FUN_004036a0(1);
}
pcVar4 = FUN_00402300(local_c);
*(char **)(param_1 + 0x2c) = pcVar4;
*(undefined4 *)(param_1 + 0x28) = 0;
local_10 = (char *)0x0;
FUN_00404088(param_2,(char *)local_8[2],s_dropzone_0051e5dc,&local_10);
if (local_10 == (char *)0x0) {
FUN_004dbb24(&DAT_00524e20,s_Error__dropzone_not_specified__0051e5e5,(char *)0x0);
FUN_004036a0(1);
}
pcVar4 = FUN_00402300(local_10);
*(char **)(param_1 + 0x28) = pcVar4;
*(undefined4 *)(param_1 + 0x3c) = 0;
FUN_004040d8(param_2,(char *)local_8[2],s_loadzones_0051e605,(int *)(param_1 + 0x3c));
*(undefined4 *)(param_1 + 0x20) = 0;
local_14 = (char *)0x0;
FUN_00404088(param_2,(char *)local_8[2],s_color_0051e60f,&local_14);
if (local_14 == (char *)0x0) {
FUN_004dbb24(&DAT_00524e20,s_Error__color_not_specified__0051e615,(char *)0x0);
FUN_004036a0(1);
}
pcVar4 = FUN_00402300(local_14);
*(char **)(param_1 + 0x20) = pcVar4;
local_18 = (char *)0x0;
FUN_00404088(param_2,(char *)local_8[2],s_patch_0051e632,&local_18);
if (local_18 == (char *)0x0) {
FUN_004dbb24(&DAT_00524e20,s_Error__patch_not_specified__0051e638,(char *)0x0);
FUN_004036a0(1);
}
FUN_00402a98((int *)&local_1c,(int *)(param_1 + 0xf8),local_18);
piVar3 = local_1c + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_1c,3);
}
*(undefined4 *)(param_1 + 0x24) = 0;
local_20 = (char *)0x0;
FUN_00404088(param_2,(char *)local_8[2],s_badge_0051e655,&local_20);
if (local_20 == (char *)0x0) {
FUN_004dbb24(&DAT_00524e20,s_Error__badge_not_specified__0051e65b,(char *)0x0);
FUN_004036a0(1);
}
pcVar4 = FUN_00402300(local_20);
*(char **)(param_1 + 0x24) = pcVar4;
iVar5 = FUN_00404088(param_2,(char *)local_8[2],s_badge_0051e678,&local_24);
if (iVar5 == 0) {
FUN_00402a98((int *)&local_2c,(int *)(param_1 + 0xec),s_DEFAULT_0051e67e);
piVar3 = local_2c + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_2c,3);
}
}
else {
FUN_00402a98((int *)&local_28,(int *)(param_1 + 0xec),local_24);
piVar3 = local_28 + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_28,3);
}
}
local_30 = s_Unspecified_0051e686;
iVar5 = FUN_00404088(param_2,(char *)local_8[2],s_experience_0051e692,&local_30);
if (iVar5 == 0) {
pcVar4 = *(char **)(param_1 + 0x2c);
pcVar8 = s_camera_0051e69d;
do {
bVar9 = *pcVar4 == *pcVar8;
if (!bVar9) break;
if (*pcVar4 == '\0') goto LAB_004d2f3e;
pcVar1 = pcVar4 + 1;
bVar9 = *pcVar1 == pcVar8[1];
if (!bVar9) break;
pcVar4 = pcVar4 + 2;
pcVar8 = pcVar8 + 2;
bVar9 = *pcVar1 == '\0';
} while (!bVar9);
if (!bVar9) {
FUN_004dbb24((int *)&DAT_00524e68,(char *)local_8[2],(char *)0x0);
FUN_004dbb24((int *)&DAT_00524e68,s_page_missing_expereince__0051e6a4,(char *)0x0);
FUN_004d9c38((int *)&DAT_00524e68);
FUN_0040385c(s_Exiting_0051e6be,s_d__tesla_bt_bt_l4_BTL4MSSN_CPP_0051e6c6,0xf0);
goto LAB_004d3052;
}
}
LAB_004d2f3e:
pcVar8 = s_Unspecified_0051e6e5;
pcVar4 = local_30;
do {
if (*pcVar8 != *pcVar4) goto LAB_004d2f68;
bVar9 = true;
if (*pcVar8 == '\0') break;
pcVar1 = pcVar8 + 1;
if (*pcVar1 != pcVar4[1]) goto LAB_004d2f68;
pcVar8 = pcVar8 + 2;
pcVar4 = pcVar4 + 2;
bVar9 = *pcVar1 == '\0';
} while (!bVar9);
if (!bVar9) {
LAB_004d2f68:
iVar5 = FUN_004d4b58(local_30,s_novice_0051e6f1);
if (iVar5 == 0) {
*(undefined4 *)(param_1 + 0xe4) = 0;
}
else {
iVar5 = FUN_004d4b58(local_30,s_standard_0051e6f8);
if (iVar5 == 0) {
*(undefined4 *)(param_1 + 0xe4) = 1;
}
else {
iVar5 = FUN_004d4b58(local_30,s_veteran_0051e701);
if (iVar5 == 0) {
*(undefined4 *)(param_1 + 0xe4) = 2;
}
else {
iVar5 = FUN_004d4b58(local_30,s_expert_0051e709);
pcVar4 = local_30;
if (iVar5 == 0) {
*(undefined4 *)(param_1 + 0xe4) = 3;
}
else {
FUN_004dbb24((int *)&DAT_00524e68,(char *)local_8[2],(char *)0x0);
FUN_004dbb24((int *)&DAT_00524e68,s_has_an_unknown_experience_field_o_0051e710,
(char *)0x0);
FUN_004dbb24((int *)&DAT_00524e68,pcVar4,(char *)0x0);
FUN_004d9c38((int *)&DAT_00524e68);
FUN_0040385c(s_Exiting_0051e735,s_d__tesla_bt_bt_l4_BTL4MSSN_CPP_0051e73d,0x108);
}
}
}
}
}
LAB_004d3052:
local_34 = 0;
bVar9 = FUN_004040d8(param_2,(char *)local_8[2],s_advancedDamage_0051e75c,&local_34);
if (CONCAT31(extraout_var,bVar9) != 0) {
if (local_34 == 0) {
*(undefined4 *)(param_1 + 0xf0) = 0;
}
else {
*(undefined4 *)(param_1 + 0xf0) = 1;
}
}
iVar5 = FUN_00404088(param_2,(char *)local_8[2],&DAT_0051e76b,&local_3c);
if (iVar5 == 0) {
FUN_004dbb24((int *)&DAT_00524e68,s_Each_Player_page_must_have_a_rol_0051e7fd,(char *)0x0);
FUN_004d9c38((int *)&DAT_00524e68);
FUN_0040385c(s_Exiting_0051e827,s_d__tesla_bt_bt_l4_BTL4MSSN_CPP_0051e82f,0x1c3);
}
else {
FUN_00402a98((int *)&local_40,(int *)(param_1 + 0xe8),local_3c);
piVar3 = local_40 + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_40,3);
}
iVar5 = FUN_00404088(param_2,local_3c,s_model_0051e770,&local_44);
if (iVar5 == 0) {
FUN_004dbb24((int *)&DAT_00524e68,local_3c,(char *)0x0);
FUN_004dbb24((int *)&DAT_00524e68,s_page_or_model_field_missing___0051e7b7,(char *)0x0);
FUN_004d9c38((int *)&DAT_00524e68);
FUN_0040385c(s_Exiting_0051e7d6,s_d__tesla_bt_bt_l4_BTL4MSSN_CPP_0051e7de,0x1bd);
}
else {
FUN_004323c7(local_90,param_1 + 0x50);
puVar6 = (undefined4 *)(**(code **)(local_90[0] + 0x54))(local_90,param_1 + 0xe8);
FUN_00432405(local_90,2);
if (puVar6 == (undefined4 *)0x0) {
puVar6 = (undefined4 *)FUN_00402298(0x2c);
if (puVar6 == (undefined4 *)0x0) {
puVar6 = (undefined4 *)0x0;
}
else {
local_48 = local_44;
local_50 = (uint *)FUN_00402298(0x10);
if (local_50 == (uint *)0x0) {
local_4c = (uint *)0x0;
}
else {
local_4c = FUN_00402460(local_50,local_48);
}
local_4c[3] = local_4c[3] + 1;
puVar6 = FUN_00429a9c(puVar6,(int *)(param_1 + 0xe8),(int *)&local_4c);
}
local_54 = local_4c;
puVar2 = local_4c + 3;
*puVar2 = *puVar2 - 1;
if (*puVar2 == 0) {
FUN_004024d8((int *)local_4c,3);
}
local_5c = puVar6 + 9;
local_60 = (int *)*local_5c;
local_60[3] = local_60[3] + 1;
local_58 = puVar6;
FUN_004323c7(local_a4,param_1 + 0x50);
iVar5 = (**(code **)(local_a4[0] + 0x54))(local_a4,&local_60);
FUN_00432405(local_a4,2);
uVar7 = (uint)(iVar5 == 0);
local_64 = local_60;
piVar3 = local_60 + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_60,3);
}
if (uVar7 != 0) {
local_68 = local_58 + 9;
local_6c = (int *)*local_68;
local_6c[3] = local_6c[3] + 1;
(**(code **)(*(int *)(param_1 + 0x50) + 8))(param_1 + 0x50,local_58,&local_6c);
local_70 = local_6c;
piVar3 = local_6c + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_6c,3);
}
}
}
iVar5 = FUN_00404118(param_2,local_3c,s_dmgInflctdMdfr_0051e776,&local_38);
if (iVar5 != 0) {
puVar6[3] = local_38;
}
iVar5 = FUN_00404118(param_2,local_3c,s_dmgRcvdMdfr_0051e785,&local_38);
if (iVar5 != 0) {
local_74 = local_38;
puVar6[4] = local_38;
}
iVar5 = FUN_00404118(param_2,local_3c,s_dmgBias_0051e791,&local_38);
if (iVar5 != 0) {
puVar6[6] = local_38;
}
iVar5 = FUN_00404118(param_2,local_3c,s_friendlyFire_0051e799,&local_38);
if (iVar5 != 0) {
puVar6[5] = local_38;
}
bVar9 = FUN_004040d8(param_2,local_3c,s_return_0051e7a6,&local_78);
if (CONCAT31(extraout_var_00,bVar9) != 0) {
puVar6[10] = local_78;
}
iVar5 = FUN_00404118(param_2,local_3c,s_killBonus_0051e7ad,&local_38);
if (iVar5 != 0) {
puVar6[7] = local_38;
}
}
}
bVar9 = FUN_004040d8(param_2,(char *)local_8[2],s_bitmapindex_0051e84e,(int *)(param_1 + 0x4c));
if (CONCAT31(extraout_var_01,bVar9) == 0) {
FUN_004dbb24(&DAT_00524e20,s_No_Bitmap_for_player_0051e85a,(char *)0x0);
FUN_004dbb24(&DAT_00524e20,(char *)local_8[2],(char *)0x0);
FUN_004d9c38(&DAT_00524e20);
}
else {
local_7c = *(undefined4 *)(param_1 + 0x4c);
iVar5 = (**(code **)(*(int *)(param_1 + 0x68) + 0xc))(param_1 + 0x68,&local_7c);
if (((iVar5 != 0) && (*(int *)(DAT_004efc94 + 0x4c) != 0)) &&
(piVar3 = *(int **)(*(int *)(DAT_004efc94 + 0x4c) + 0x1c530), piVar3 != (int *)0x0)) {
(**(code **)(*piVar3 + 0x28))
(piVar3,1,0,0xff,0,0,0,0,iVar5,0,0,*(int *)(iVar5 + 0xc) + -1,
*(int *)(iVar5 + 0x10) + -1);
(**(code **)(*piVar3 + 8))(piVar3,1);
(**(code **)(*piVar3 + 0xc))(piVar3);
}
}
piVar3 = local_8 + 3;
*piVar3 = *piVar3 + -1;
if (*piVar3 == 0) {
FUN_004024d8(local_8,3);
}
return;
}