feat(reconstruction): complete binary-backed C recovery
Replace the partial mechanics transcriptions with a separate, readable C11 reconstruction of the complete Win16 image while preserving the original raw Ghidra export as immutable evidence. Cover all ordinary and overlapping entry points, Borland runtime behavior, Win16 imports, segmented data, callbacks, resources, indirect control flow, physics, rendering, persistence, and startup/shutdown lifecycles. Add deterministic extraction and audit tooling plus address-linked ledgers for functions, imports, DGROUP ranges and objects, relocations, resources, and callbacks. The final gate records zero raw, partial, restored, unknown, blocked, or unclassified required units. Keep the semantic-fidelity boundary explicit: the portable C is not claimed to reproduce a byte-identical Borland NE build. Add strict focused harnesses for every reconstructed C unit, exact resource round-trip checks, and a 16-bit Borland Real48 reference probe. No Rust source or Cargo metadata is changed in this phase. Test Plan: - `bash original/tools/test_reconstructed_c.sh` -- passed - `bash original/tools/probe_real48_reference.sh` -- passed bit-for-bit - `python3 original/tools/audit_reconstruction.py --require-complete` -- passed - `git diff --cached --check` -- passed - `git diff HEAD -- '*.rs' Cargo.toml Cargo.lock` -- empty
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
#ifndef TDKPIN_GAMEPLAY_HELPERS_H
|
||||
#define TDKPIN_GAMEPLAY_HELPERS_H
|
||||
|
||||
#include "tdkpin_render.h"
|
||||
|
||||
void tdkpin_blit_bitmap_and_present(
|
||||
HBITMAP16 bitmap,
|
||||
INT16 height,
|
||||
INT16 width,
|
||||
INT16 y,
|
||||
INT16 x,
|
||||
HDC16 dc); /* 1000:635c */
|
||||
void tdkpin_restore_bounds_overlay_a(
|
||||
uint16_t ignored_static_link,
|
||||
INT16 bottom,
|
||||
INT16 right,
|
||||
INT16 top,
|
||||
INT16 left,
|
||||
HDC16 dc); /* 1000:b2c8 */
|
||||
void tdkpin_restore_bounds_overlay_b(
|
||||
uint16_t ignored_static_link,
|
||||
INT16 bottom,
|
||||
INT16 right,
|
||||
INT16 top,
|
||||
INT16 left,
|
||||
HDC16 dc); /* 1000:b3b0 */
|
||||
void tdkpin_draw_score_from_caller_frame(
|
||||
uint16_t caller_bp,
|
||||
uint16_t value_low,
|
||||
uint16_t value_high); /* 1000:bda2 */
|
||||
void tdkpin_set_gameplay_transition_flags(
|
||||
uint16_t caller_bp); /* 1000:a70e */
|
||||
uint16_t tdkpin_receiver_point_in_bounds(
|
||||
uint16_t caller_bp,
|
||||
int32_t maximum_y,
|
||||
int32_t maximum_x,
|
||||
int32_t minimum_y,
|
||||
int32_t minimum_x); /* 1000:9ae0 */
|
||||
uint16_t tdkpin_ball_in_bounds(
|
||||
uint16_t ignored_static_link,
|
||||
int32_t maximum_y,
|
||||
int32_t maximum_x,
|
||||
int32_t minimum_y,
|
||||
int32_t minimum_x); /* 1000:9b69 */
|
||||
void tdkpin_update_dynamic_ball_record(
|
||||
uint16_t ignored_static_link,
|
||||
int32_t record_displacement); /* 1000:bdde */
|
||||
void tdkpin_restore_record_or_item_a(
|
||||
uint16_t caller_bp, uint16_t id); /* 1000:b30b */
|
||||
void tdkpin_restore_record_b(
|
||||
uint16_t caller_bp, uint16_t id); /* 1000:b3f3 */
|
||||
void tdkpin_refresh_collision_record(
|
||||
uint16_t caller_bp, uint16_t id); /* 1000:7e12 */
|
||||
void tdkpin_refresh_player_item(
|
||||
uint16_t caller_bp, uint16_t item); /* 1000:7e92 */
|
||||
void tdkpin_load_ball_slot(
|
||||
uint16_t caller_bp, uint16_t slot); /* 1000:c36b */
|
||||
void tdkpin_save_ball_slot(
|
||||
uint16_t caller_bp, uint16_t slot); /* 1000:c426 */
|
||||
void tdkpin_draw_board_decoration_row(
|
||||
uint16_t caller_bp, INT16 y); /* 1000:6b37 */
|
||||
void tdkpin_draw_board_decoration_row_on_dc(
|
||||
INT16 y, HDC16 dc); /* semantic core used by 1000:6bf8 */
|
||||
void tdkpin_render_ball_from_caller_frame(
|
||||
uint16_t caller_bp); /* 1000:9bca */
|
||||
void tdkpin_reset_ball_state(
|
||||
uint16_t caller_bp); /* 1000:9e85 */
|
||||
void tdkpin_refresh_player_progress_markers(
|
||||
uint16_t caller_bp); /* 1000:a604 */
|
||||
void tdkpin_composite_player_sprite(
|
||||
uint16_t sprite_index, HDC16 reference_dc); /* 1000:0002 */
|
||||
void tdkpin_add_score_from_caller_frame(
|
||||
uint16_t caller_bp, int32_t delta); /* 1000:bc36 */
|
||||
void tdkpin_restore_previous_ball_region(
|
||||
uint16_t caller_bp, uint8_t suppress_present); /* 1000:a38e */
|
||||
void tdkpin_render_ball_swept_region(
|
||||
uint16_t caller_bp); /* 1000:9f73 */
|
||||
void tdkpin_move_ball_and_render(
|
||||
uint16_t caller_bp,
|
||||
int32_t delta_x,
|
||||
int32_t delta_y); /* 1000:beff */
|
||||
|
||||
extern uint8_t g_player_count; /* 1028:07d0 */
|
||||
extern uint8_t g_gameplay_transition_pending; /* 1028:07c9 */
|
||||
extern int32_t g_ball_x_milli; /* 1028:07d3..07d6 */
|
||||
extern int32_t g_ball_y_milli; /* 1028:07d7..07da */
|
||||
extern uint8_t g_current_player; /* 1028:07d1 */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user