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.
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.cfgcontrolling 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
BinkHandletoLocalDatausing thread-local or global array indexed by storage ID
3. Function Interception (bik_descriptor.hpp/cpp)
- Linked-list of
BinkFunctionDescriptorobjects 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
SubtitleFileobjects, 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
.srtfiles 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
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_GENERATEdefined) for export list generation
Key compiler flags:
CMF_LIB_EXPORT/CMF_LIBpreprocessor symbols control DLL vs executable builds_CRT_SECURE_NO_WARNINGSsuppresses CRT function warningsIgnoreAllDefaultLibraries+ explicit dependency onCMFrameworkD.libandlibcmtd.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
-
Library Load (
DllMaininbik_main.cpp)- Calls
initLibrary()which loads config frombinkw32.cfg - Initializes descriptor list
- Creates thread-local storage for per-video state
- Calls
-
Video Open (e.g.,
BinkOpen)- Allocate
LocalDatawith frame buffer - Search for matching subtitle files
- Forward to real Bink library
- Allocate
-
Frame Playback Loop
BinkDoFrame: Copy video frame data toFrameBuffer.canvas(GDI+ surface)BinkWait: Render frame and subtitles- Update FPS counter and log diagnostics if enabled
-
Cleanup (
BinkClose,DllMainunload)- Release frame buffers and subtitle lists
- Close log file
- Single INI file at
./binkw32.cfgwith sections:[general],[bink],[log],[subtitle],[font],[video],[plugin] - Utilities:
iniGetBool(),iniGetString(),iniGetInteger()from CMFramework - Example:
config.showFps = iniGetBool(iniPath, "general", "show_fps", True);
- 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)
- Conditional at compile-time:
logDebug(),logError(),logCall(functionName, parameterCount) - Clustered mode groups related logs together
- Output to
./binkw32.logand optional stderr
- Searches for
.srtfiles in paths specified bysubtitle_search_pathconfig - 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
fontRightToLeftflag
- Thread safety: Consider local storage array indexed by
storageIndex(implicitly assumes single-threaded playback perBinkHandle) - Track state: 32-bit array (
TrackState[32]) tracks which audio tracks are enabled - Frame buffer reuse: Allocated once per video, reused across frame playback
Test Configuration:
- The
Test|Win32target compiles as an.exewithBINK_GENERATEdefined - Used for validating export list generation before final DLL build
Debugging approaches:
- Enable
debug=truein subtitle section for render diagnostics - Enable
log.*options and checkbinkw32.logfor call tracing error_check=truein bink section enables post-call error validation
Adding a new config option:
- Add field to
GlobalConfigstruct inbik_internal.hpp - Load in
initLibrary()withiniGetXxx(iniPath, sectionName, "key", defaultValue) - Use in relevant handler functions
Hooking a new Bink function:
- Add typedef and structure in
bik_public.hppif needed - Create descriptor:
static BinkFunctionDescriptor myFunc("FunctionName", paramCount); - Add export line to
export.defwith ordinal - 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.totalSecondandendTime.totalSecond
- 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_pathin config
| 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