Files
ReSkate/Engine/Game/Build/20260929/no_bail.h
T
2026-10-02 14:40:41 -05:00

124 lines
8.0 KiB
C++

#pragma once
#include "Engine/Game/Build/fingerprint.h"
namespace dingosdk::game::build::v20260929::no_bail {
// Supported SHA-256 fbce74d5e28ef525dbba2cb4adbebc13405bdbd88f31bc940bca45e4ae88b8f9.
// void(collector, int32 reason, float magnitude): writes cause byte +0x28,
// XMM2 magnitude to +0x4c, and increments cause count +0xe0. Both the full
// wipeout and recoverable runout predicates consume this collector.
inline constexpr Fingerprint record_bail_cause_contract{0x4753c20, {
0x48,0x63,0xc2,0xc6,0x44,0x08,0x28,0x01,0xc5,0xfa,0x11,0x54,0x81,0x4c,0xff,0x81,
0xe0,0x00,0x00,0x00,0xc3,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc}};
inline constexpr Fingerprint choose_physics_state_contract{0x4745a70, {
0x40,0x53,0x55,0x56,0x57,0x41,0x55,0x41,0x57,0x48,0x81,0xec,0xc8,0x00,0x00,0x00,
0x8b,0x41,0x40,0x8b,0xf2,0x48,0x8b,0xd9,0x85,0xc0,0x7e,0x05,0xff,0xc8,0x89,0x41}};
inline constexpr Fingerprint bail_animation_caller_contract{0x47da94c, {
0xe8,0xaf,0x67,0xff,0xff,0x84,0xc0,0x75,0x27,0x48,0x8b,0x8f,0x28,0x04,0x00,0x00,
0xe8,0x6f,0x2b,0xf7,0xff,0x84,0xc0,0x75,0x13,0x48,0x8b,0x87,0xc0,0x03,0x00,0x00}};
inline constexpr Fingerprint bail_state_caller_contract{0x47da1cf, {
0x48,0x8b,0x8b,0x40,0x04,0x00,0x00,0x8b,0xd0,0x8b,0xf0,0xe8,0x91,0xb8,0xf6,0xff,
0x8b,0xf8,0xb8,0xf8,0x01,0x00,0x00,0x81,0xff,0x2c,0x01,0x00,0x00,0x0f,0x44,0xf8}};
// The optimizer inlines several cause producers (for example +2a/+54/+e0
// at 0x474b27c), bypassing record_bail_cause_contract. Use the native per-step
// reset at consumption boundaries to cover those producers too. This complete
// leaf clears 35 cause bytes, 35 magnitudes and the count, leaving owner/config
// pointers and other collector fields untouched. It has no external calls.
inline constexpr std::uintptr_t reset_bail_causes_rva = 0x474cca0;
inline constexpr std::array<unsigned char, 0x88> reset_bail_causes_code{
0x33,0xc0,0x89,0x81,0xe0,0x00,0x00,0x00,0x48,0x89,0x41,0x28,0x48,0x89,0x41,0x4c,
0x48,0x89,0x41,0x54,0x48,0x89,0x41,0x5c,0x48,0x89,0x41,0x64,0x48,0x89,0x41,0x30,
0x48,0x89,0x41,0x6c,0x48,0x89,0x41,0x74,0x48,0x89,0x41,0x7c,0x48,0x89,0x81,0x84,
0x00,0x00,0x00,0x48,0x89,0x41,0x38,0x48,0x89,0x81,0x8c,0x00,0x00,0x00,0x48,0x89,
0x81,0x94,0x00,0x00,0x00,0x48,0x89,0x81,0x9c,0x00,0x00,0x00,0x48,0x89,0x81,0xa4,
0x00,0x00,0x00,0x48,0x89,0x41,0x40,0x48,0x89,0x81,0xac,0x00,0x00,0x00,0x48,0x89,
0x81,0xb4,0x00,0x00,0x00,0x48,0x89,0x81,0xbc,0x00,0x00,0x00,0x48,0x89,0x81,0xc4,
0x00,0x00,0x00,0x66,0x89,0x41,0x48,0x48,0x89,0x81,0xcc,0x00,0x00,0x00,0x88,0x41,
0x4a,0x89,0x81,0xd4,0x00,0x00,0x00,0xc3,
};
// The post-physics skeleton response takes (rig, float dt, bool wipeout).
// The animation publisher takes the physics core. Both consume the explicit
// request at context+13c4 bit 15 and the independent request at +13d4 bit 27.
inline constexpr Fingerprint bail_skeleton_contract{0x4777eb0, {
0x48,0x8b,0xc4,0x48,0x89,0x58,0x10,0x57,0x48,0x81,0xec,0x10,0x01,0x00,0x00,0x48,
0x8b,0xd9,0xc5,0xf8,0x29,0x70,0xe8,0xc5,0xf8,0x29,0x78,0xd8,0x48,0x8b,0x01,0x45}};
inline constexpr Fingerprint bail_publish_contract{0x47da450, {
0x48,0x8b,0xc4,0x57,0x48,0x81,0xec,0xf0,0x00,0x00,0x00,0x48,0x89,0x58,0x08,0x48,
0x8b,0xf9,0x48,0x8b,0x89,0xb8,0x03,0x00,0x00,0x48,0x89,0x70,0x10,0xc5,0x78,0x29}};
// Native consumers: skeleton caller's request test and ABI, animation's
// +87 explicit request export, and +8d independent request export. No Bail
// leaves the separate native recover/runout output at +9e alone.
inline constexpr std::array<Fingerprint, 4> bail_consumer_contracts{{
{0x47da40b, {
0x48,0x8b,0x8b,0xc0,0x03,0x00,0x00,0xf7,0x81,0xd4,0x13,0x00,0x00,0x00,0x00,0x00,
0x08,0x74,0x05,0x41,0xb0,0x01,0xeb,0x03,0x45,0x32,0xc0,0x48,0x8b,0x83,0xc0,0x03}},
{0x47da426, {
0x48,0x8b,0x83,0xc0,0x03,0x00,0x00,0x48,0x8b,0xcf,0xc5,0xfa,0x10,0x88,0xec,0x17,
0x00,0x00,0x48,0x8b,0x5c,0x24,0x30,0x48,0x83,0xc4,0x20,0x5f,0xe9,0x69,0xda,0xf9}},
{0x47da8d7, {
0x8b,0x90,0xc4,0x13,0x00,0x00,0x48,0x8b,0x87,0xb8,0x03,0x00,0x00,0xc1,0xea,0x0f,
0x80,0xe2,0x01,0x48,0x8b,0x48,0x38,0x88,0x91,0x87,0x00,0x00,0x00,0x48,0x8b,0x87}},
{0x47da965, {
0x48,0x8b,0x87,0xc0,0x03,0x00,0x00,0xf7,0x80,0xd4,0x13,0x00,0x00,0x00,0x00,0x00,
0x08,0x74,0x04,0xb0,0x01,0xeb,0x02,0x32,0xc0,0x88,0x83,0x8d,0x00,0x00,0x00,0x48}},
}};
// The sensitive body-contact report bypasses the cause collector. Native
// collision processing sets +0x10fe for configured body bones hitting a solid
// object; the rig publisher exports it to contacts+0xfb8. It is imported into
// context+0x13c4 bit 22 (also tested by the Wipeout selector), and separately
// into the animation contact context at +0xd6 by 0x102cbe0. Verify all three
// transfer sites. The independent recent-contact latch at +0x2c3 stays native.
inline constexpr std::array<Fingerprint, 3> body_contact_contracts{{
{0x4769c7d, {
0x48,0x8b,0x83,0x10,0x2f,0x00,0x00,0x48,0x8b,0x4f,0x30,0x48,0x8b,0x80,0x40,0x10,
0x00,0x00,0x0f,0xb6,0x80,0xfe,0x10,0x00,0x00,0x88,0x81,0xb8,0x0f,0x00,0x00,0x48}},
{0x47d914d, {
0x48,0x8b,0x48,0x30,0x41,0x8b,0x90,0xc4,0x13,0x00,0x00,0x0f,0xb6,0x81,0xb8,0x0f,
0x00,0x00,0xc1,0xe0,0x16,0x33,0xc2,0x25,0x00,0x00,0x40,0x00,0x33,0xc2,0x41,0x89}},
{0x102f7a9, {
0x49,0x8b,0x9f,0xb0,0x0c,0x00,0x00,0xff,0x90,0xb0,0x00,0x00,0x00,0x48,0x8b,0x48,
0x30,0x0f,0xb6,0x81,0xb8,0x0f,0x00,0x00,0x49,0x8b,0xcf,0x88,0x83,0xd6,0x00,0x00}},
}};
inline constexpr std::uintptr_t body_contact_output_offset = 0xfb8;
inline constexpr std::uintptr_t body_contact_context_offset = 0x13c4;
inline constexpr LONG body_contact_context_mask = 0x400000;
inline constexpr std::uintptr_t animation_request_offset = 0x13d4;
inline constexpr LONG animation_request_mask = 0x08000000;
// These collision producers set context+13c4 bit 15 immediately before
// recording the cause. Animation reads that request independently of the cause
// collector; cancel both at these verified call sites, leaving other flags alone.
struct ImpactBail {
Fingerprint caller;
std::int32_t reason;
std::uintptr_t return_rva;
};
inline constexpr std::array<ImpactBail, 3> impact_bail_calls{{
{{0x47f2026, {
0xba,0x0d,0x00,0x00,0x00,0x48,0x8b,0x01,0xc5,0xe8,0x57,0xd2,0x81,0x88,0xc4,0x13,
0x00,0x00,0x00,0x80,0x00,0x00,0x48,0x8b,0x49,0x08,0xe8,0xdb,0x1b,0xf6,0xff,0x40}}, 13, 0x47f2045},
{{0x47fa6cc, {
0xba,0x09,0x00,0x00,0x00,0x49,0x8b,0x06,0xc5,0xe8,0x57,0xd2,0x81,0x88,0xc4,0x13,
0x00,0x00,0x00,0x80,0x00,0x00,0x49,0x8b,0x4e,0x08,0xe8,0x35,0x95,0xf5,0xff,0x49}}, 9, 0x47fa6eb},
{{0x47fa780, {
0xba,0x0e,0x00,0x00,0x00,0x49,0x8b,0x06,0xc5,0xe8,0x57,0xd2,0x81,0x88,0xc4,0x13,
0x00,0x00,0x00,0x80,0x00,0x00,0x49,0x8b,0x4e,0x08,0xe8,0x81,0x94,0xf5,0xff,0x48}}, 14, 0x47fa79f},
}};
inline constexpr std::uintptr_t impact_request_offset = 0x13c4;
inline constexpr LONG impact_request_mask = 0x8000;
// uint32(selector, current): core+0x440 owns the selector, selector+8 is
// core+0x3c0's context. The caller remaps WipeoutGround (300) to Offboard (504).
// Filter 300 before that remap; 504 also means ordinary walking, so allow it.
inline constexpr std::uint32_t wipeout_physics_state = 300;
// Offboard (walking), and the selector's test of the animation's mount request: context
// +13d4 bit 7 (bit 8 is the dismount request). While a S.K.A.T.E. player waits for their
// turn on foot (throwdown_relay.h), the request is dropped before the selector reads it.
inline constexpr std::uint32_t offboard_physics_state = 504;
inline constexpr LONG mount_request_mask = 0x80;
inline constexpr Fingerprint mount_request_test_contract{0x4746a94, {
0x48,0x8b,0x53,0x08,0xf6,0x82,0xd4,0x13,0x00,0x00,0x80,0x0f,0x84,0x6f,0xf4,0xff,
0xff,0x48,0x8b,0x82,0xb0,0x0d,0x00,0x00,0x48,0x85,0xc0,0x74,0x15,0x48,0x83,0xe0}};
inline constexpr std::uintptr_t bail_core_vtable = 0x6176d30;
// Native recovery/stumble predicate. Its result is also exported to animation
// at +0x9e, so No Bail never forces it. Reference only.
inline constexpr std::uintptr_t recovery_predicate = 0x47d1100;
}