Skip to content

Latest commit

 

History

History
162 lines (125 loc) · 7.83 KB

File metadata and controls

162 lines (125 loc) · 7.83 KB

BikMod - AI Coding Agent Instructions

Project Overview

BikMod is a Bink video codec interceptor DLL for Windows that wraps and enhances the native Bink library (binkw32.dll). It provides:

  • Video playback interception with custom frame buffer management
  • Subtitle rendering and track selection
  • Configuration via INI files (binkw32.cfg)
  • Function hooking through DLL replacement with decorated name exports
  • Multi-track audio support with runtime track state management
  • Frame-by-frame playback control and diagnostics

Critical architecture pattern: This is NOT a complete Bink implementation—it's a proxy/wrapper that intercepts and modifies calls to the real Bink library while delegating core video/audio operations.

Architecture

Core Components

1. Public API Layer (bik_public.hpp)

  • Defines Bink data structures used by client applications: BinkVideo, BinkSound, BinkBuffer, BinkTrack
  • Callback function pointer types for I/O operations (BinkIoOpenFunction, BinkIoReadFrameFunction, etc.)
  • Sound system callbacks for audio management
  • These are the external-facing interfaces that games expect

2. Internal Module (bik_internal.hpp/cpp)

  • LocalData: Per-video-instance state including frame buffers, current audio track, and subtitle lists
  • FrameBuffer: Manages Windows window handle, GDI+ canvas, pixel pitch, and surface type
  • GlobalConfig: Singleton loaded from binkw32.cfg controlling feature toggles (subtitles, logging, FPS display, video rescaling)
  • BinkLibrary: Tracks version info, audio track state flags (32 tracks max), and HMODULE handles to real Bink DLL
  • Local Storage: Maps BinkHandle to LocalData using thread-local or global array indexed by storage ID

3. Function Interception (bik_descriptor.hpp/cpp)

  • Linked-list of BinkFunctionDescriptor objects that track decorated function names and both original and current addresses
  • Name decoration: Uses MSVC calling convention formatting (_FuncName@ParameterBytes)
  • Dual addressing: Stores original address (from real binkw32.dll) and current address (patched hook)
  • Initialized at library load; descriptors register themselves in constructor

4. Subtitle System (bik_subtitle.hpp)

  • Linked-list of SubtitleFile objects, one per audio track
  • SubtitleEntry: Time ranges with linked list of text lines
  • SubtitleTime: Bit-packed time struct (hour, minute, second, millisecond) + totalSecond field
  • Auto-searches for matching .srt files in configured paths during video open

5. Utility/Version Management

  • bik_version.hpp: Version parsing macros and string constants (e.g., "0.3f" → major=0, minor=3, micro='f'-'a')
  • bik_utils.hpp: Function name decoration and export generation helpers

Build Configuration

Targets (from bikmod.vcxproj):

  • Debug|Win32: DLL output to D:\Games\Rage\ with debug info
  • Release|Win32: DLL with optimization enabled
  • Test|Win32: Console executable (preprocessor BINK_GENERATE defined) for export list generation

Key compiler flags:

  • CMF_LIB_EXPORT / CMF_LIB preprocessor symbols control DLL vs executable builds
  • _CRT_SECURE_NO_WARNINGS suppresses CRT function warnings
  • IgnoreAllDefaultLibraries + explicit dependency on CMFrameworkD.lib and libcmtd.lib
  • Include path: ..\..\CMFramework\include\ (external framework dependency)

Linking:

  • Module definition file: export.def (defines 100+ Bink function exports with ordinals)
  • All Bink functions are re-exported with decorated names pointing to interceptor stubs

Data Flow

  1. Library Load (DllMain in bik_main.cpp)

    • Calls initLibrary() which loads config from binkw32.cfg
    • Initializes descriptor list
    • Creates thread-local storage for per-video state
  2. Video Open (e.g., BinkOpen)

    • Allocate LocalData with frame buffer
    • Search for matching subtitle files
    • Forward to real Bink library
  3. Frame Playback Loop

    • BinkDoFrame: Copy video frame data to FrameBuffer.canvas (GDI+ surface)
    • BinkWait: Render frame and subtitles
    • Update FPS counter and log diagnostics if enabled
  4. Cleanup (BinkClose, DllMain unload)

    • Release frame buffers and subtitle lists
    • Close log file

Important Patterns & Conventions

Configuration System

  • Single INI file at ./binkw32.cfg with sections: [general], [bink], [log], [subtitle], [font], [video], [plugin]
  • Utilities: iniGetBool(), iniGetString(), iniGetInteger() from CMFramework
  • Example: config.showFps = iniGetBool(iniPath, "general", "show_fps", True);

Function Hooking

  • Original Bink functions are loaded dynamically: HMODULE hBinkLibrary = LoadLibrary("binkw32_original.dll")
  • Decorated names enable function interception: client calls _BinkOpen@8, which redirects to our stub
  • Each descriptor maintains both original address (from real Bink) and current address (our wrapper)

Logging

  • Conditional at compile-time: logDebug(), logError(), logCall(functionName, parameterCount)
  • Clustered mode groups related logs together
  • Output to ./binkw32.log and optional stderr

Subtitle Rendering

  • Searches for .srt files in paths specified by subtitle_search_path config
  • Renders over video frame using font properties from config (family, size, weight, color, outline)
  • Time sync: Subtitle entry displayed if currentTime >= startTime && currentTime <= endTime
  • Right-to-left text support via fontRightToLeft flag

State Management

  • Thread safety: Consider local storage array indexed by storageIndex (implicitly assumes single-threaded playback per BinkHandle)
  • Track state: 32-bit array (TrackState[32]) tracks which audio tracks are enabled
  • Frame buffer reuse: Allocated once per video, reused across frame playback

Testing & Debugging

Test Configuration:

  • The Test|Win32 target compiles as an .exe with BINK_GENERATE defined
  • Used for validating export list generation before final DLL build

Debugging approaches:

  • Enable debug=true in subtitle section for render diagnostics
  • Enable log.* options and check binkw32.log for call tracing
  • error_check=true in bink section enables post-call error validation

Common Tasks

Adding a new config option:

  1. Add field to GlobalConfig struct in bik_internal.hpp
  2. Load in initLibrary() with iniGetXxx(iniPath, sectionName, "key", defaultValue)
  3. Use in relevant handler functions

Hooking a new Bink function:

  1. Add typedef and structure in bik_public.hpp if needed
  2. Create descriptor: static BinkFunctionDescriptor myFunc("FunctionName", paramCount);
  3. Add export line to export.def with ordinal
  4. Implement wrapper in appropriate module (internal, public, etc.)

Modifying subtitle rendering:

  • Edit subtitle rendering code (typically in frame update path)
  • Respects config: showSubtitles, subtitlePlacementX/Y, subtitleAlignmentX/Y, all font properties
  • Time comparison uses SubtitleEntry.startTime.totalSecond and endTime.totalSecond

External Dependencies

  • CMFramework: Custom framework providing utility functions (iniGetXxx, logXxx, CStringList, Color, Graphics::Canvas)
  • GDI+: Windows graphics library for canvas rendering
  • Original Bink DLL: Dynamically loaded at runtime; path configurable via library_file_path in config

Key File Reference

File Purpose
bik_internal.hpp/cpp Core state management (LocalData, FrameBuffer, GlobalConfig)
bik_public.hpp Bink API structures and callback types
bik_descriptor.hpp/cpp Function descriptor registry for hooking
bik_subtitle.hpp Subtitle data structures and loading
bik_main.cpp DLL entry point (DllMain)
export.def DLL export definitions with ordinals
bikmod.vcxproj Build configuration

Last updated: January 2026 | Version: 0.3f