RetroArch 成就系统内核 rcheevos 版本演进全解析:从 v1.0.0 到 v12.4.0 的功能架构与关键变更
【免费下载链接】RetroArchCross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.项目地址: https://gitcode.com/GitHub_Trending/re/RetroArch
rcheevos 是 RetroArch 内置成就系统(cheevos 模块)所依赖的第三方 C 库,负责解析与评估 RetroAchievements 数据、生成游戏哈希、与服务器交互,是成就系统目录底层实现的核心引擎。本文以仓库内 deps/rcheevos/CHANGELOG.md 为主体骨架,结合 deps/rcheevos/README.md、deps/rcheevos/include/ 与 deps/rcheevos/src/ 源码,系统梳理该库从 v1.0.0 到 v12.4.0 的演进脉络,读者可以借此理解成就系统的四层架构(触发解析、运行时、哈希、服务端通信)及各版本的能力边界与破坏性变更。
一、rcheevos 在 RetroArch 中的定位
rcheevos 是一套纯 C 代码库,目标是让模拟器更容易处理 RetroAchievements 数据,为玩家提供成就与排行榜支持。它不提供 HTTP 网络连接,客户端必须自行从 RetroAchievements 获取数据,再交给 rcheevos 处理——这一点在 README 中有明确说明。
在 RetroArch 中,该库被 cheevos/cheevos.c 直接引用,例如#include "../deps/rcheevos/include/rc_runtime.h"、#include "../deps/rcheevos/include/rc_hash.h"、#include "../deps/rcheevos/src/rc_libretro.h",说明其头文件与源码是以源码级方式编译进 RetroArch 的,而不是作为动态链接库。
从当前源码结构看,库由四个主要子系统构成,这正好与 CHANGELOG 的演进主线一一对应:
| 子系统 | 目录/头文件 | 职责 |
|---|---|---|
| rcheevos 核心 | src/rcheevos/ | 触发器、条件集、排行榜、富文本状态(rich presence)的解析与求值 |
| rc_client | include/rc_client.h、src/rc_client.c | 高层客户端抽象:登录、识别/加载游戏、成就列表、事件回调 |
| rapi | src/rapi/、include/rc_api_*.h | 构建服务器 API 请求并解析响应,同样不做网络请求 |
| rhash | src/rhash/、include/rc_hash.h | 根据游戏文件生成 RetroAchievements 哈希,用于游戏识别 |
这四层对应到版本号上:早期版本(v1~v6)主要打磨 rcheevos 核心触发器引擎,v8 引入富文本与运行时,v10 引入 rapi 并重构 rhash,v11 引入 rc_client 高层接口,v12 则对三者进行大规模增强与重构。
二、v1~v6:核心解析引擎的奠基期
早期的 CHANGELOG 记录的是最底层的触发器解析与求值 API 的建立过程:
- v1.0.0:第一个版本,提供最基础的
memaddr解析与求值能力。 - v2.0.0:移除了排行榜回调,改为更简单的方案,简化了调用模型。
- v3.x:加入
rc_format_value(数值格式化)与格式化字符串解析;v3.0.1 修复 64 位平台上 32 位值读取错误。 - v4.0.0:修复
rc_parse_trigger中ret未初始化的问题;对外暴露rc_parse_value与rc_evaluate_value以支持富文本;移除 API 中的reset与dirty标志。 - v5.0.0:预计算条件组内是否存在暂停条件,并在条件集中增加标志位,避免运行时反复扫描链表。
- v6.x:加入 24 位操作数(
RC_OPERAND_24_BITS,前缀'W');新增 rurl(构建访问 RetroAchievements Web 服务的 URL 的 API)与 rjson(解码 RetroAchievements JSON 到 C 结构);新增控制台标识枚举(对应今天的 include/rc_consoles.h);v6.0.0 将 API 简化为"先获取缓冲区大小、再解析到缓冲区"的两段式调用,并让调用方负责传入 scratch buffer,避免越界访问。
这一阶段的成果奠定了今日数据结构的基础:在 include/rc_runtime_types.h 中可以看到操作数类型(RC_OPERAND_ADDRESS、RC_OPERAND_DELTA、RC_OPERAND_PRIOR、RC_OPERAND_BCD、RC_OPERAND_RECALL等)、条件类型(RC_CONDITION_PAUSE_IF、RC_CONDITION_RESET_IF、RC_CONDITION_MEASURED、RC_CONDITION_AND_NEXT、RC_CONDITION_OR_NEXT等)以及运算符枚举(RC_OPERATOR_EQ、RC_OPERATOR_MULT、RC_OPERATOR_MOD等)。
三、v7~v8:富文本、运行时与条件标志的突破
- v7.x:新增
RC_DISABLE_LUA宏以支持无 Lua 编译;保证 C89 兼容;Lua 中使用 32 位类型;仅在 Lua 状态非空时求值 Lua 操作数;修复内存分配对齐。 - v8.0.0:这是能力跃升的版本——支持 prior 操作数类型、支持
AndNext条件标志、正式支持富文本(rich presence),并修复了分组暂停期间 delta/prior 值的更新问题。v8.1.0 又加入RC_CONDITION_MEASURED、RC_CONDITION_ADD_ADDRESS标志,新增RC_FORMAT_MINUTES、RC_FORMAT_SECONDS_AS_MINUTES格式,并将rc_evaluate_value的返回值改为有符号整数。
v8 引入的"条件标志"体系在 include/rc_runtime_types.h 的RC_CONDITION_*枚举中完整保留,成为后续版本触发器语义扩展的根基。
四、v9~v10:新尺寸、新标志与哈希/API 分层
v9.0.0是另一个关键里程碑:
- 新增内存尺寸
RC_MEMSIZE_BITCOUNT; - 新增条件标志
RC_CONDITION_OR_NEXT、RC_CONDITION_TRIGGER、RC_CONDITION_MEASURED_IF; - 新增运算符
RC_OPERATOR_MULT/RC_OPERATOR_DIV; is_bcd从 memref 中移除,并入RC_MEMSIZE;- 新增
rc_runtime_t及关联函数、rc_hash_*函数族、rc_error_str、rc_console_*函数。
v10.0.0是一次大型重构:
- 新增rapi 子库用于与服务器通信(消除了客户端自行解析 JSON 的需求,客户端仍需提供 HTTP 能力),rurl 被标记废弃(v12.0.0 彻底移除);
rhash.h重命名为rc_hash.h,rconsoles.h、rurl.h同步改名以保持一致;- 非运行时函数从
rcheevos.h拆分出去; - 富文本查找支持范围(ranges);
- 新增
RC_CONDITION_RESET_NEXT_IF、RC_CONDITION_SUB_HITS; - 排行榜值表达式支持
MAXOF运算符($)以及RC_CONDITION_PAUSE_IF/RC_CONDITION_RESET_IF; - 哈希相关 handler 的偏移参数从
size_t改为int64_t,以支持 32 位编译模式下大于 2GB 的文件; - 新增 Dreamcast、PlayStation 2、Supervision、TIC-80 的哈希支持,并完成大量控制台枚举重命名。
v10.x 系列继续扩展:v10.1 增加RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED与rc_runtime_validate_addresses;v10.3 引入浮点内存尺寸与逻辑、内置富文本宏(@Number、@Score、@Centisecs、@Seconds、@Minutes、@ASCIIChar、@UnicodeChar);v10.5 新增RC_MEMSIZE_MBF32_LE、RC_OPERATOR_XOR及一批小众主机;v10.6 新增RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED并引入针对常见条件逻辑的优化比较器;v10.7 新增 Gamecube、DSi、TI-83、Uzebox 的哈希/内存映射。当前 include/rc_consoles.h 中 RC_CONSOLE 枚举已超过 80 个主机编号(含 Famicom Disk System、WASM4、Arduboy 等),正是这条扩展主线持续积累的结果。
五、v11:rc_client 高层客户端与 raintegration 初登场
v11.0.0 引入了rc_client_t及其关联函数,这是集成方式的重大转折:开发者不再需要手动拼接 rapi 调用与运行时求值,而是通过rc_client_create、rc_client_begin_identify_and_load_game等高层函数管理登录、游戏识别、成就激活与 UI 事件。同版本还加入RC_MEMSIZE_FLOAT_BE、GBA 内存映射、Super Cassettevision 哈希方法,并将rc_api_process_*_server_response扩展为接收 status_code 与 body_length。
v11.1.0 继续补全 rc_client 能力:
rc_client_get_user_agent_clause生成客户端 User-Agent 片段;rc_client_can_pause控制暂停上报频率;- 成就类型(type)与稀有度(rarity)加入
rc_api_fetch_game_data_response_t与rc_client_achievement_t; - 新增
RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED(本地已解锁但未同步服务器的成就桶); - 新增 NINTENDO_3DS(新增 src/rhash/aes.c 支持加密哈希)、MS-DOS 哈希逻辑;
- 新增
RC_FORMAT_FIXED1/2/3、RC_FORMAT_TENS、RC_FORMAT_HUNDREDS、RC_FORMAT_THOUSANDS、RC_FORMAT_UNSIGNED_VALUE格式; - 新增
RC_CONSOLE_STANDALONE; - 公开函数统一加
extern "C"与__cdecl属性,便于 C++ 与跨编译单元链接; - 提供
rc_version/rc_version_string供外部链接获取版本; - 初始(未完成)支持
rc_client_external_t与rc_client_raintegration_t。
v11.2~v11.6 持续完善:RC_CLIENT_SUPPORTS_HASH编译开关允许 rc_client 在无 rhash 文件(除 md5.c 外)下构建;rc_client_raintegration_set_console_id、rc_client_raintegration_get_achievement_state、rc_client_raintegration_set_get_game_name_function等 raintegration 辅助函数逐步补齐;RC_MEMSIZE_DOUBLE32/RC_MEMSIZE_DOUBLE32_BE加入内存尺寸枚举;RC_CLIENT_RAINTEGRATION_EVENT_MENU_CHANGED事件新增;ZX Spectrum 哈希与内存映射、Gamecube ISO 支持、DS/DSi 的 DTCM 映射等主机支持继续扩充。
六、v12:大规模重构与能力收口
v12.0.0 是本仓库当前版本线中最具分量的重构版本,分为四个方面:
6.1 rc_client 增强
- 新增
RC_CLIENT_EVENT_SUBSET_COMPLETED事件; - 用户、游戏、成就结构体新增
avatar_url、badge_url、badge_locked_url字段; - 新增
rc_client_set_hash_callbacks与rc_client_set_allow_background_memory_reads; rc_client_begin_change_media更名为rc_client_begin_identify_and_change_media,原rc_client_begin_change_media_from_hash更名为rc_client_begin_change_media;- Windows 上
rc_mutex在 Vista+ 使用精简读写锁,旧版 Windows 使用临界区; rc_client_external增加跨版本翻译层。
6.2 rhash 重构
rc_hash_init_verbose_message_callback、rc_hash_init_error_message_callback、rc_hash_init_custom_filereader、rc_hash_init_custom_cdreader、rc_hash_generate_from_file、rc_hash_generate_from_buffer全部废弃,改为在rc_hash_iterator_t的 callbacks 中设置,并使用rc_hash_initialize_iterator+rc_hash_generate组合——这一模式在 include/rc_hash.h 的 README 示例与头文件注释中均有体现;- hash.c 拆分为多个可条件编译的文件:
RC_HASH_NO_DISC(排除 hash_disc.c)、RC_HASH_NO_ENCRYPTED(排除 hash_encrypted.c)、RC_HASH_NO_ROM(排除 hash_rom.c)、RC_HASH_NO_ZIP(排除 hash_zip.c),这正对应 src/rhash/ 中hash_disc.c、hash_encrypted.c、hash_rom.c、hash_zip.c的分文件结构; - 新增 Wii、Arduboy FX 哈希方法。
6.3 rapi 变化
- 新增
_hosted变体的rc_api_init函数以支持自定义主机,rc_api_set_host与rc_api_set_image_host废弃; - 新增
rc_api_fetch_game_sets、rc_api_fetch_followed_users、rc_api_fetch_hash_library、rc_api_fetch_all_user_progress; - 登录、成就信息、排行榜信息响应增加
avatar_url,game_data 响应增加badge_url; - rurl 被正式移除(v10.0.0 起废弃)。
6.4 触发器解析与处理性能优化
AddAddress/AddSource链可在触发器间共享,避免重复计算;- 触发器预处理将条件从链表改为数组分配,数组按条件类型(pause/reset/hittarget 等)排序,同类条件可一起处理而无需多次扫描链表;链表仍保留以维持向后兼容与原始顺序;
- 每种条件类型拥有独立 handler,消除了处理触发器时的大量 switch/分支;
- memref 改为数组分配,从每个元素中移除链表指针以降低内存占用。
6.5 数值格式化变更
从 v12.0.0 起,除 SCORE 外的所有数字格式默认插入千分位逗号,并新增@Unformatted(UNFORMATTED)格式用于显示不带逗号的数字。为向后兼容地强制排除逗号,可使用@Unformatted宏并将 Unformatted 定义为 VALUE 格式:旧客户端会使用 VALUE 格式化,新客户端则使用@Unformatted宏。
6.6 其他 v12.0.0 变更
- 新增
RC_CONSOLE_FAMICOM_DISK_SYSTEM(从RC_CONSOLE_NINTENDO拆分); - SNES 内存映射支持 SA-1 I-RAM 与 BW-RAM;SEGACD 映射支持 WORD RAM;N64 映射将 RDRAM 置于
$80000000、扩展包 RAM 置于$80400000; - 移除
HAVE_LUA定义与支持(实现从未完成); - 富文本中包含以
0x0x开头的地址时报告错误; - 新增 .natvis 文件以改进 Visual Studio 调试体验。
6.7 v12.1~v12.4 的持续修补
- v12.1.0:新增
rc_client_get_user_subset_summary;为使用 MeasuredIf 而无 Measured、使用 ResetIf 而无命中目标补充校验警告;新增 update_rich_presence 的 rapi 函数;Wii 内存映射增加 gap 便于指针转换;修复浮点 Remember、富文本中 MeasuredIf 求值、SubSource 链校验、rc_client_allow_background_memory_reads调用时序、混合新旧格式宏导致的内存损坏等。 - v12.2.0:新增
rc_client_create_subset_list与rc_client_begin_fetch_game_titles(对应 include/rc_client.h 中的rc_client_create_subset_list/rc_client_destroy_subset_list与rc_client_begin_fetch_game_list等系列接口);大幅提升长 AddSource 链的解析性能;不处理帧时不发送 ping,允许服务器在模拟器暂停时挂起会话;校验逻辑改为返回最严重错误而非首个错误;修复无限循环、浮点取整、缓冲区溢出等。 - v12.3.0:新增
rc_client_get_next_achievement_info(在 include/rc_client.h 中声明为"获取指定成就之后、符合指定桶的下一个成就");rc_client 图片函数在缓冲区不足时返回RC_INSUFFICENT_BUFFER而非截断;修复上一游戏的富文本关联到当前游戏的竞态、隐藏排行榜误报、大成就解析内存泄漏等。 - v12.4.0(当前版本线最新):为
rc_client_user_t与rc_api_login_response_t增加avatar_last_updated字段(在 include/rc_client.h 的rc_client_user_t中可见/* minimum version: 12.4 */ time_t avatar_last_updated;注释);扩展 fetch_games_list API 字段;新增rc_client_begin_fetch_game_list;为 PSP 内存映射增加扩展 RAM、新增 XBOX 内存映射;新增 .neo(geolith 专用 NeoGeo ROM)哈希生成;当同一地址与值同时存在 Mem 与 Delta 条件时输出校验警告;修复{recall}无 Remember 时崩溃、旧版值含非法语法溢出转换缓冲区、以常量开头的 SubSource 链处理等。
七、错误码体系与校验器演进
CHANGELOG 多次提到校验警告(validation warning)与错误码,这些在 include/rc_error.h 中有完整落地:RC_OK为 0,其余为负值错误码,涵盖解析类(RC_INVALID_*)、缺失类(RC_MISSING_*)、状态类(RC_NO_GAME_LOADED、RC_HARDCORE_DISABLED)、网络类(RC_API_FAILURE、RC_ACCESS_DENIED、RC_INVALID_CREDENTIALS、RC_EXPIRED_TOKEN、RC_INSUFFICIENT_BUFFER)等 40 个返回值,可通过rc_error_str转为人类可读字符串。
校验器本身的演进也很清晰:v10.3.3 开始"检测校验器中的逻辑冲突与冗余";v10.5 起不再报告触发器与非触发器条件之间的冗余、不报告浮点比较的范围校验错误;v11.3 对多条件逻辑报告校验错误;v12.0 校验逻辑改为返回最严重错误;v12.2 完善了 PauseIf/Remember/ResetIf/AndNext 相关的警告语义;v12.4 新增 Mem/Delta 同地址同值警告。
八、与 RetroArch 的集成方式
在 RetroArch 中,成就功能位于 cheevos/ 目录,其中 cheevos/cheevos.c 直接包含 rcheevos 的运行时、哈希头文件与rc_libretro.h,说明 RetroArch 通过rc_libretro 适配层把 libretro 核心的内存读取能力桥接到 rcheevos 的哈希与求值流程上。仓库还提供了 cheevos/cheevos.h、cheevos/cheevos_locals.h、cheevos/cheevos_menu.c、cheevos/cheevos_client.c 等文件,分别承担菜单展示与客户端交互。若需为自定义模拟器集成成就系统,推荐直接使用rc_client_t高层 API(创建→登录→识别并加载游戏→每帧处理运行时→通过事件回调更新 UI),并自行提供内存读取回调与 HTTP 回调。
九、破坏性变更速查(集成迁移参考)
对正在升级依赖的开发者,CHANGELOG 中的破坏性变更可汇总如下:
| 版本 | 破坏性变更 |
|---|---|
| v6.0.0 | 解析 API 改为两段式(先取缓冲区大小再解析),调用方需传入 scratch buffer |
| v7.0.0 | 移除 rjson |
| v9.0.0 | memref 中移除 is_bcd,并入 RC_MEMSIZE |
| v10.0.0 | rurl 废弃;rhash.h/rconsoles.h/rurl.h 改名;非运行时函数从 rcheevos.h 拆出;CD 轨道参数与文件 seek 偏移类型变更 |
| v11.0.0 | 强类型化替换宽松类型(unsigned → uint32_t 等);compat.c 上移改名 rc_compat.c |
| v12.0.0 | rurl 移除;rc_client_begin_change_media系列更名;rhash 初始化函数与生成函数废弃并迁移到 iterator.callbacks;移除 HAVE_LUA;默认数字格式插入逗号(可用 @Unformatted 兼容) |
结语
从 v1.0.0 的单一触发器解析器,到 v12.4.0 融合 rc_client、rapi、rhash、rc_runtime 四层体系的完整成就引擎,rcheevos 的 CHANGELOG 记录了 RetroArch 成就系统底层近十年的演进细节。当前 deps/rcheevos/include/ 中的 15 个头文件与 deps/rcheevos/src/ 中按 rapi/rcheevos/rhash 划分的源码目录,正是这些版本迭代沉淀出的最终形态,也是理解 RetroArch 成就功能实现原理的最佳入口。
【免费下载链接】RetroArchCross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.项目地址: https://gitcode.com/GitHub_Trending/re/RetroArch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考