源代码结构地图¶
目标读者:想学习本项目并参与开发的个人开发者。 用法:先看下方整体树抓住骨架,再按模块深入;每段"树 + 说明"告诉你这个目录/文件负责什么、该怎么读。 建议搭配:architecture.md(数据流/桥接)、key-references.md(关键符号)、 getting-started.md(入门)、build.md(构建)。 树中
//后的文字是对该目录/文件职责的速记。
0. 顶层一览¶
PocketKrKr/ (= 仓库根目录)
├── apps/flutter_app/ // Flutter 壳应用(UI、游戏管理、本地化)
│ └── lib/ // Dart 前端源码(main + pages/services/...)
├── bridge/
│ ├── engine_api/ // C ABI 引擎桥(engine_create/tick/destroy/...)
│ └── flutter_engine_bridge// Flutter 平台插件(IOSurface/SurfaceTexture + FFI)
├── cpp/
│ ├── core/ // C++ 引擎核心(TVP/TJS2)
│ ├── plugins/ // TJS 插件(psb/psd/layerex/motionplayer/fstat/...)
│ └── external/ // 内置三方(libbpg、minizip)
├── build.sh + build/*.sh // 一键构建
├── CMakeLists.txt+CMakePresets.json // MacOS/iOS/Android/Linux 预设
├── vcpkg.json + vcpkg/ // 依赖与 triplet
└── docs/ // 文档(GitHub Pages + dev/ 开发文档)
1. bridge/ — C ABI 桥接层(C++ 与 Dart 的交界)¶
1.1 engine_api/¶
稳定 C ABI,是 Dart 侧能调用的唯一入口。头部定义了版本号 ENGINE_API_VERSION,保证 ABI 兼容。
engine_api/include/engine_api.h // C 头:引擎生命周期/输入/帧读取/内存统计的函数原型
engine_api/include/engine_options.h // 引擎启动参数结构(窗口大小、存档路径、是否开调试等)
engine_api/src/engine_api.cpp // C ABI 实现:engine_create/tick/destroy、ReadFrameRgba 回读、
// 输入转发、探针上报(黑屏诊断)等
engine_api/src/engine_api_android_jni.cpp // Android JNI 胶水:Kotlin 驱动 surface 初始化 & 生命周期
阅读入口:
engine_api.h的函数签名(约十几个函数)→ 逐个到.cpp看实现。改动接口时 必须同步 bump 版本号。
1.2 flutter_engine_bridge/¶
Flutter 平台插件包(plugin),把引擎的零拷贝纹理接到 Flutter,同时暴露 FFI 绑定。
lib/src/ffi/engine_bindings.dart // FFI 绑定:engine_api.h 的 Dart 声明(指针/结构体/回调)
lib/src/ffi/engine_ffi.dart // 加载 dylib/.so/RN,封装调用(FFI 优先路径)
lib/flutter_engine_bridge.dart // 对外主类:给 Flutter 壳用的高层 API
lib/flutter_engine_bridge_platform_interface.dart // 平台通道抽象
lib/flutter_engine_bridge_method_channel.dart // MethodChannel 兜底实现
ios/Classes/FlutterEngineBridgePlugin.swift // iOS/macOS:IOSurface 纹理注册给 Flutter
macos/Classes/FlutterEngineBridgePlugin.swift // 同上(macOS 版本)
android/.../FlutterEngineBridgePlugin.kt // Android:SurfaceTexture(JNI) 纹理注册
阅读顺序:
flutter_engine_bridge.dart(对外)→engine_ffi.dart(加载/调用)→ 平台.swift/.kt(纹理)。
2. cpp/core/ — C++ 引擎核心(最重要的部分)¶
cpp/core/
├── base/ // 引擎基础:存档/字节流/字符集/KAG/事件/脚本/存储接口
├── tjs2/ // TJS2 脚本语言虚拟机(解释器/编译器/字节码/Core 对象)
├── environ/ // 应用生命周期、主循环、平台抽象、全局配置
├── visual/ // 渲染:Bitmap/Layer/字体/图像编解码 + GL/OGL/SIMD
├── sound/ // 音频:Wave/CD/MIDI/解码/效果
├── movie/ // 视频(ffmpeg 播放)
├── plugin/ // 插件宿主:ncbind 双向绑定
└── utils/ // 底层工具:容器/线程/编码/数学/RNG/定时器
2.1 base/ — 引擎基础设施¶
存放"引擎执行需要但非渲染"的通用能力,多为 Intf(接口) + Impl(平台实现) 成对出现。
base/impl/ // 各平台的实现(iOS/Android/Windows 共用一套源,靠宏守卫)
EventImpl.* // 事件系统(原生键盘/触摸 → TVP 事件)
NativeEventQueue.* // 原生事件队列
MsgImpl.* // 弹窗/Message 实现
FileSelector.* // 文件选择框
ScriptMgnImpl.* // 脚本管理(脚本块缓存、全局作用域)
StorageImpl.* // 磁盘存储(存档/读取文件流)
SysInitImpl.* / SystemImpl.*// 引擎初始化与系统对象实现
base/StorageIntf.* // 存储接口:Open/Exist/GetFileInfo 等(读存档/配包)
base/ScriptMgnIntf.* // 脚本引擎接口:Eval/EvalExpression(TJS2 宿入口)
base/SystemIntf.* // 系统层接口:延迟暂停/ExitingHandler/崩溃转储
base/EventIntf.* / MsgIntf.* // 事件/消息接口
base/XP3Archive.* / ZIPArchive.* / 7zArchive.* / TARArchive.*
// 归档读取器:XP3(本体素材包)/ZIP/7z/TAR
base/KAGParser.* // KAG(KAG3 脚本标签)解析
base/BinaryStream.* / TextStream.* / CharacterSet.*
// 字节流/文本流/字符集转换(GBK/JIS/UTF-8)
base/UtilStreams.* // 工具流(包装/过滤流)
base/UserEvent.h // 用户事件定义
2.2 tjs2/ — TJS2 脚本语言虚拟机¶
让游戏脚本(.tjs/.ks)能跑起来的核心。包含词法→语法→字节码→解释执行全链路。
tjs2/bison/*.y // 语法:tjs.y(TJS 主语法)、tjsdate.y(日期)、tjspp.y(预处理)
tjs2/script/ // 生成世界地图表 + 停用词表(词法辅助)
tjs.cpp / tjs.h // 主入口:VM 从句柄启动、字符串/脚本注册
tjsLex.* // 词法分析(lexer)
tjsInterCodeGen.* // 中间代码生成(字节码结构)
tjsInterCodeExec.* // 字节码解释执行(大跳转表 VM)
tjsCompileControl.* // 编译控制(优化开关、即时编译配置)
tjsByteCodeLoader.* // 字节码加载/反序列化(运行已编译脚本)
tjsScriptBlock.* // 脚本块(源码→代码块的编译单元)
tjsScriptCache.* // 脚本编译缓存
S 内置对象:
tjsObject.* // 对象/原型链(TJS 一切皆派生)
tjsObjectExtendable.* // 可扩展对象
tjsArray.* / tjsConstArrayData.* / tjsDictionary.* // Array/ConstArray/Dictionary
tjsVariant.* / tjsVariantString.* // Variant 万能值 & 字符串
tjsString.* // 字符串(UTF-16、写时复制/全局映射)
tjsGlobalStringMap.* // 全局字符串驻留表(省内存)
tjsFunction(经 Native/Interface) // 见 tjsNative.* 原生方法绑定
tjsMath.* / tjsRandomGenerator.* // 数学 & 随机(MT19937:tjsMT19937ar-cok)
tjsDate.* / tjsDateParser.* // 日期与解析
tjsRegExp.* // 正则
tjsException.* / tjsError.* // 异常/错误
tjsDebug.* / tjsDisassemble.* // 调试器 & 反汇编(看字节码用)
tjsBinarySerializer.* // 二进制序列化(跨会话对象持久化)
tjsNative.* // 原生(native)方法/类注册路径
tjsInterface.* / tjsNamespace.* // interface 与命名空间
tjsConfig.* // VM 配置
tjsOctPack.* // 位打包工具
学习建议:跑一个"Hello"脚本,跟随
tjs.cpp→ lex → 编译 →tjsInterCodeExec执行,是理解 TJS2 最快路径。
2.3 environ/ — 生命周期、主循环与平台¶
引擎"从开机到跑起来"的骨架,以及跨平台抽象层。
environ/EngineBootstrap.* // 引擎引导:加载配置、初始化子系统顺序
environ/EngineLoop.* // 主循环:每帧执行脚本定时器/事件/渲染 tick
environ/MainScene.* // 主场景(舞台)宿主
environ/Application.* // App 应用对象
environ/GlobalConfigManager.* // 全局配置(ini 读写)
environ/IndividualConfigManager.* // 每游戏配置
environ/LocaleConfigManager.* // 多语言配置
environ/DumpSend.cpp // 崩溃转储发送
environ/DetectCPU.* // CPU 特性检测(决定 SIMD 派发)
environ/XP3ArchiveRepack.* // XP3 重打包工具
environ/Platform.h // 平台抽象头
environ/android/platform_android.cpp // Android 平台实现
environ/apple/ios/platform.mm // iOS 平台实现(Objective-C++)
environ/apple/macos/platform.mm // macOS 平台实现
environ/sdl/tvpsdl.cpp // SDL 平台实现(CI/Linux 宿主、SDL 窗口)
environ/stubs/platform_linux.cpp // Linux CI 宿主验证用 stub
environ/stubs/ui_stubs.cpp // 无窗口 stub:探针上报(UpdateDrawBuffer → draw 状态)
environ/win32/ // Win32 共享实现(音频/线程/系统控制,跨平台复用,勿删)
environ/typedefine.h / cpu_types.h / vkdefine.h / combase.h // 基础类型/平台宏
ui_stubs.cpp里能看到黑屏探针(SourceSample/PostBlit/draw/BlackScreen上报),排查黑屏从这里入手。
2.4 visual/ — 渲染(最复杂、坑最多)¶
Bitmap/图层/文字/图像加载/OpenGL 渲染/SIMD 混合,全都在这。
visual/BitmapIntf.* // 位图接口(Surface/图层位图)
visual/LayerIntf.* // 图层接口(场景里一层一层的东西)
visual/LayerManager.* / LayerTreeOwnerImpl.* // 图层树管理
visual/BasicDrawDevice.* // 基础绘制设备(CPU 软绘)
visual/DrawDevice.* // 绘制设备抽象(软/GL 选择)
visual/LayerBitmapImpl.* / LayerImpl.* // 图层/位图实现
visual/ImageFunction.* // 图像处理函数(缩放/混合)
visual/Load*.cpp // 图像解码:LoadPNG/WEBP/JPEG/TLG/BPG/JXR/AMV/PVRv3
visual/tvpgl.cpp / tvpgl.h // 像素级混合函数(对照 SIMD 的标准标量实现!)
visual/argb.* // ARGB 像素格式与操作
visual/FontSystem.* / FreeType* / NativeFreeTypeFace.* / GDIFontRasterizer.*
// 字体系统:FreeType 光栅化 + 系统字体
visual/CharacterData.* // 字符数据(字形)
visual/PrerenderedFont.* // 预渲染字体(提速)
visual/RenderManager.* / RenderManager_software.h // 渲染管理(合成/提交)
visual/VideoOvlImpl.* / VideoOvlIntf.* // 视频覆盖层
visual/WindowImpl.* / WindowIntf.* // 窗口抽象
visual/TransIntf.* // 转场
visual/SaveTLG5/6.* // TLG(KiriKiri 专有位图)写出
visual/gl/ // GL 标量像素函数:blend_function/blend_functor_c 等
visual/ogl/ // OpenGL 后端:krkr_egl_context(EGL+ANGLE)、krkr_gl、纹理、
// etcpak/astc/pvrtc 压缩纹理、图像打包 imagepacker
visual/simd/ // Highway SIMD 像素混合:tvpgl_simd_*(alpha/arithmetic/blur/
// const/convert/copy/misc/premul/ps_blend)tvpgl_simd_init 派发
⚠️ 高亮:
tvpgl.cpp的*_c标量实现是正确基准;simd/*曾检出 23 处与标量不一致, 高危模式已指回标量。改混合公式前先比对标量(见 conventions.md)。
2.5 sound/ — 音频¶
sound/WaveIntf.* / SoundBufferBaseIntf.* / CDDAIntf.* / MIDIIntf.* // 接口(波形段/CD/MIDI)
sound/WaveLoopManager.* // 波形循环管理
sound/WaveSegmentQueue.* // 波形段队列(流式/叠加)
sound/WaveFormatConverter.* // 格式转换(+ SSE 版)
sound/FFWaveDecoder.* / VorbisWaveDecoder.* // WAV / Vorbis 解码
sound/PhaseVocoderDSP.* / PhaseVocoderFilter.* // 变调不变速(相位声码器)
sound/MathAlgorithms.* // 数学算法
sound/xmmlib.cp // 播放内核(MCI/DSound 时代遗留的共享混合内核)
sound/win32/* // 平台音频:tvpsnd 设备、WaveImpl、Mixer
2.6 movie/ffmpeg/ — 视频播放(媒体框架)¶
movie/ffmpeg/ 是重构的播放框架(源自 Kodi 风格分层):
Demux* // 解封装(DemuxFFmpeg)
VideoPlayer* / VideoPlayerVideo / VideoPlayerAudio // 播放器与音视频线程
VideoRenderer* / VideoReferenceClock* / VideoCodec / AudioCodec // 渲染/时钟/编解码
KRMoviePlayer / KRMovieLayer // KiriKiri 电影层 API 接入
BitstreamStats / CodecUtils / Thread / Timer / MessageQueue // 基座工具
krffmpeg.* // 入口:把播放器注册成 TVP 电影引擎
2.7 plugin/ — 插件宿主与 ncbind¶
plugin/ncbind.cpp / ncbind.hpp // ncbind:用模板让 C++ 函数/类自动暴露给 TJS
plugin/PluginImpl.* / PluginIntf.* // 插件加载(.tjs / .dll 插件)与生命周期
plugin/ncb_foreach.inc // ncbind 遍历辅助
2.8 utils/ — 底层工具¶
utils/ObjectList.h / Defer(common) // 容器/RAII
utils/ThreadIntf.* / TimerIntf.* / TickCount.* // 线程/定时器/毫秒时钟
utils/ClipboardIntf.* / DebugIntf.* / PadIntf.*// 剪贴板/调试输出/外设
utils/CharacterSet / encoding/iconv // 字符集(gbk2unicode/jis2unicode)
utils/MathAlgorithms_Default.* / RealFFT_Default.* // 数学/FFT 软实现
utils/Random.* / md5.c // 随机/哈希
utils/VelocityTracker.* // 手势速度跟踪
utils/win32/ // 平台共享实现(ThreadImpl/TimerImpl/Clipboard 等)
3. cpp/plugins/ — TJS 脚本插件(给游戏加能力)¶
每个插件编译后由脚本 Plugins.link 加载,向 TJS 暴露类/函数。
plugins/psbfile/ // PSB(Live2D 专用二进制包)解析:ArchiveType/Image/Motion/...Type + PSBValue
plugins/psdfile/ // PSD 解析:psdparse 子目录分层文件/图层/资源
plugins/layerex_draw/ // LayerEx 扩展绘制:DrawPath(路径)、LayerExDraw(gdi 风格)
plugins/motionplayer/ // 动感播放器(小动画序列):Player/EmotePlayer/ResourceManager
plugins/fstat/ // 文件状态/统计
plugins/json/ // JSON 读写绑定
plugins/kagparserex/ // KAG 解析扩展
plugins/steam/ // Steam 相关
plugins/DrawDeviceForSteam/ // Steam 绘制设备
plugins/cubism/ // Live2D Cubism(SDK 存在才编,缺库正常)
根目录散文件: // 大量单文件插件/兼容层
krkrlive2d.cpp / krkrgles.cpp / alphaMovie / alphamovie
drawDeviceD2DCompat / textrender / scriptsEx / saveStruct / varfile
wfBasicEffectCompat / wfTypicalDSPCompat / wutcwf / fftgraph / xp3filter
extrans / csvParser / dirlist / getSample / getabout / addFont
windowEx / win32dialog / layerEx*.cpp / simplebinder(simplebinder.hpp)
想加自定义功能时,最简做法是仿照任一插件写
main.cpp+CMakeLists.txt,用 ncbind 暴露类。
4. apps/flutter_app/ — Flutter 前端(UI 全在这)¶
apps/flutter_app/lib/
├── main.dart // App 入口:初始化引擎桥、路由、主题
├── engine/
│ ├── engine_bridge.dart // 引擎状态机:create→open_game→tick 生命周期、加载 flutter_engine_bridge
│ └── flutter_engine_bridge_adapter.dart // 把平台插件适配成立即可用的桥
├── pages/
│ ├── home_page.dart // 首页:游戏列表、导入
│ ├── game_page.dart // 游戏页:承载 EngineSurface,运行引擎主循环
│ ├── game_detail_page.dart // 游戏详情
│ ├── scrape_select_page.dart // 元数据抓取选择
│ └── settings_page.dart // 设置(版本、存储、调试开关)
├── widgets/
│ ├── engine_surface.dart // 把 NativeTexture(Texture) 与手势 → engine_bridge 绑定的组件
│ └── performance_overlay.dart // 性能/FPS 覆盖层(调试)
├── services/
│ ├── game_manager.dart // 游戏管理:导入 XP3/配包、扫描、启停
│ ├── cover_downloader.dart // 封面下载
│ ├── game_metadata_scraper.dart // 元数据抓取
│ ├── vndb_client.dart // VNDB API 客户端
│ └── first_open_analytics.dart// 首次打开统计
├── models/
│ ├── game_info.dart // 游戏信息模型
│ └── game_metadata_candidate.dart // 抓取候选模型
├── config/ // stats_base_url 等
├── constants/prefs_keys.dart // SharedPreferences 键名集中管理
├── utils/xp3_utils.dart // XP3 工具(校验/读取元数据)
└── l10n/ // 多语言:app_zh/en/ja.arb + app_localizations*.dart
阅读顺序:
main.dart→engine/engine_bridge.dart(掌握引擎生命周期) →widgets/engine_surface.dart(掌握纹理+输入如何接入)→pages/(各页面)。 引擎相关只通过flutter_engine_bridge+engine_bridge.dart进出,别在页面里直接碰 FFI。
5. 给开发者的三条指引¶
- 想先跑起来:跟 build.md(
./build.sh),iOS 静态库、Android.so、macOS dylib 各自成形。 - 想加一个游戏脚本功能:改
cpp/(引擎能力)→ bump 版本号; 或写插件放cpp/plugins/,用 ncbind 暴露给 TJS。 - 想加一个 UI/页面:全在
apps/flutter_app/lib/pages+widgets,需要引擎对象就拿engine_bridge.dart。
保持同步:本文件随目录结构变动更新;改动平台目录时同步 conventions.md。