☰
mGBA 贡献指南:从 Issue 提报到编码规范与 MPL 2.0 许可合规的完整实践
2026/9/28 2:45:55 网站建设 项目流程
  • 游戏开发

【免费下载链接】mgba

mGBA Game Boy Advance Emulator

项目地址:https://gitcode.com/gh_mirrors/mg/mgba
点击查看免费下载

mGBA 是一个以 C 和 C++ 编写的 Game Boy Advance 模拟器,同时支持 Game Boy / Game Boy Color 与 Super Game Boy,代码覆盖 ARM7 核心、GBA/GB 两套模拟核心、Qt 与 SDL 前后端以及 3DS、Switch、Vita、Wii 等多个移植平台。本文以仓库根目录下的 CONTRIBUTING.md 为骨架,结合仓库源码与目录结构,系统讲解向 mGBA 提交 Issue、发起 Pull Request 时必须遵循的流程、组件命名、编码风格与许可要求。读完本文,你将能规范地提报带完整诊断信息的 bug 报告,写出符合 mGBA 风格的 C/C++ 代码,并避免在合并环节被要求返工或直接关闭 PR。

提报 Issue:一份高质量 bug 报告的三要素

mGBA 的 Issue 需要提交到项目的问题跟踪器。在提报时,官方要求至少包含三部分信息,它们共同决定了问题能否被快速定位与复现。

构建版本号:定位问题的第一把钥匙

mGBA 要求提供你正在使用的构建版本。对于近期构建,版本号直接显示在标题栏中,格式形如:

0.3-2134-4ec19aa

这个字符串由四段组成,从左到右依次是:

  • 版本号:如0.3,对应当前开发版本;
  • 分支名:若不在master分支上会显式标注(示例中未标注即为master);
  • 修订计数:如2134,即当前提交在历史中的序号;
  • 截断的修订哈希:如4ec19aa,即该提交的短哈希。

如果本地存在尚未提交的改动,版本号末尾还会追加-dirty后缀。

这套版本号的生成逻辑可以在仓库根目录的 version.cmake 中找到:构建系统通过git describe --always --dirty、git symbolic-ref --short HEAD、git rev-list HEAD --count等命令分别抓取短哈希、分支名与修订计数,再按master/非master分支组合出VERSION_STRING,最终通过configure_file写入版本源文件。版本数据最终以全局变量的形式暴露给运行时,定义在 include/mgba/core/version.h(如gitCommit、gitCommitShort、gitBranch、gitRevision、projectVersion等),其取值在 src/core/version.c.in 中由 CMake 模板展开,Qt 前端的“关于”对话框(见 AboutScreen.cpp)与更新器(见 ApplicationUpdater.cpp)都会读取这些常量用于显示与比对。

对于0.2.1这类旧版构建,标题栏没有版本号,此时需要手动说明你下载或编译的是哪个具体版本。如果你是从源码自行构建,git describe --always输出的描述字符串就是最准确的标识。

运行环境:软硬件信息缺一不可

  • 操作系统:例如 Windows 7 32-bit 或 Ubuntu 15.04 64-bit;
  • CPU 与显卡:如 Core i5-3570K 与 AMD Radeon R9 280X(通常不是必需的,仅在怀疑与硬件相关的渲染、性能问题时提供)。

问题描述:越详细越好

请尽可能详尽地描述问题,包括:

  • 复现问题的游戏名称;
  • 进入异常状态的具体操作路径(如何一步步触发 bug)。

若适用,mGBA 还允许将存档文件(savestate)重命名为.png后缀后直接作为附件挂到 Issue 上——存档本身即附带了运行快照,维护者可以直接加载复现,这比纯文字描述高效得多。

提交 Pull Request:组件命名与提交信息规范

发起 PR 之前,请确认你的改动符合下述编码风格,并了解许可要求(见后文“许可”一节)。此外,所有提交必须满足两点:

  1. 提交信息前后一致、可读;
  2. 提交信息中包含被修改组件的名称。

重要提醒:mGBA 明确声明不接受 AI 生成的代码。若 PR 中的代码由 AI 生成,该 PR 将被直接关闭(summarily closed)。

组件命名表

mGBA 将代码库划分为多个组件,PR 提交信息应以组件名开头。官方组件列表如下:

组件名含义
ARM7ARM 核心
GBAGBA 代码
GBA Memory内存相关
GBA Video视频、渲染
GBA Audio音频处理
GBA SIO串行 I/O、多人联机、link
GBA Hardware附加设备,如陀螺仪、光传感器
GBA BIOS高层 BIOS
GBGB 代码
GB Memory内存相关
GB Video视频、渲染
GB Audio音频处理
GB MBC内存控制器 / 卡带硬件
GB SIO串行 I/O、多人联机、link
Core各模拟核心共享的基础设施
QtQt 移植相关代码
SDLSDL 移植相关代码(含其他移植中的使用)
Util公共工具代码
Tools杂项工具
Debugger内置调试功能
3DS3DS 移植
SwitchSwitch 移植
VitaVita 移植
WiiWii 移植
mGUI各 homebrew 移植共享的 UI 代码
All不涉及特定组件、影响整个项目的改动

需要注意的是,该列表并非穷尽,涉及具体文件时,查看相关文件的提交日志(commit log)往往能给出更准确的组件归属。在仓库中,这些组件与目录结构一一对应:ARM 核心在 src/arm,GBA 与 GB 的代码分别在 src/gba 与 src/gb,共享基础设施在 src/core,Qt 与 SDL 前端分别在 src/platform/qt 与 src/platform/sdl,工具代码在 src/util 与 src/tools,各移植平台则位于 src/platform 下。

编码风格:mGBA 的代码书写规范

mGBA 致力于保持代码库的一致与整洁,因此对贡献代码有明确约束。PR 中存在风格错误时,维护者会要求先修正再合并。以下规范全部以“好/坏”对照的形式给出,可直接作为自查清单。

命名规则

  • 变量名(含函数参数):一律使用 camelCase。
  • 文件作用域 static 变量:必须以下划线_开头。
  • C 结构体名:以大写字母开头;与该结构体相关的函数应以“类名”(含大写字母)开头、后续使用 camelCase。C 结构体不得被typedef。
  • 与结构体无关的函数:整体使用 camelCase;此类 static 函数必须以下划线_开头。
  • 枚举值与#define:全部大写、以下划线分隔。

正确示例:

static int _localVariable; struct LocalStruct { void (*methodName)(struct LocalStruct struct, param); int memberName; }; enum { ENUM_ITEM_1, ENUM_ITEM_2 }; void LocalStructCreate(struct LocalStruct* struct); void functionName(int argument); static void _LocalStructUse(struct LocalStruct* struct); static void _function2(int argument2);

在仓库源码中可以大量观察到这套规则的落地。例如 include/mgba/core/core.h 中,struct mCore以大写m开头且未被 typedef,枚举mPlatform使用全大写mPLATFORM_GBA、mPLATFORM_GB形式,其成员与相关函数(如mCoreInit、mCoreLoadFile系列)均遵循“类名前缀 + camelCase”的命名模式;核心内部则普遍采用_前缀的 file-scoped static 变量。

C++ 命名规则:C++ 类应限定在命名空间内。对于 Qt 移植,该命名空间名为QGBA——在 src/platform/qt 下几乎所有头文件(如 AboutScreen.h、Action.h)都可见namespace QGBA { ... }的包裹。类名的处理方式与 C 结构体类似;成员字段按作用域加前缀:

  • m_:非 static 成员;
  • s_:static 成员。

花括号

  • 花括号不独占一行,只有收尾的}单独成行;
  • 条件子句与花括号之间要有一个空格;
  • 即使是单行块,也必须使用花括号。

正确写法:

if (condition) { block; } else if (condition2) { block2; } else { block3; }

错误写法(花括号独占一行):

if (condition) { block; } else if (condition2) { block2; } else { block3; }

错误写法(缺失花括号):

if (condition) statement; else if (condition2) statement2; else statement3;

错误写法(缺少空格):

if (condition){ block; }

缩进与对齐

  • 缩进使用制表符(tab),并与花括号层级保持一致;
  • 行内对齐应尽量克制使用,且只能用空格做对齐。

头文件保护宏(Header Guards)

C 头文件:保护宏应为文件名(含H后缀)的全大写形式,标点替换为下划线,且#endif后不得加注释:

#ifndef FILE_NAME_H #define FILE_NAME_H // Header #endif

仓库中几乎所有 C 头文件都遵循这一模式,例如 include/mgba/core/core.h 的M_CORE_H、include/mgba/core/version.h 的VERSION_H等。

Qt(C++)头文件:保护宏以QGBA_开头,且不包含_H后缀,其余规则相同。这是出于历史兼容原因,未来可能调整:

#ifndef QGBA_FILE_NAME #define QGBA_FILE_NAME // Header #endif

其他规则

  • 块语句(if、while、for)的关键字与括号之间必须有一个空格:

    正确:while (condition) {;错误:while(condition) {。

  • C 代码中:用0而非NULL(历史原因,未来可能调整);布尔场景应使用bool类型及true/false,而不是1/0。

  • C++ 代码中:使用nullptr,而不是NULL或0。

  • 无函数体的语句:不必加花括号,可以直接用分号收尾。这是建议而非强制:

    正确:while (f());;错误:while (f()) {}。

  • 内部含有break的无限循环:优先使用while (true),而非for (;;)。

许可:MPL 2.0 下的代码引入边界

mGBA 采用 Mozilla Public License version 2.0(仓库根目录的 LICENSE 文件即该许可证全文)。向 mGBA 贡献代码时,这一点会带来若干明确约束:

  • 新增代码将默认以MPL 2.0授权;
  • GPL 许可的代码不能合入上游,但可以在编译时与 mGBA 链接;
  • MIT、BSD、CC0 等宽松许可的代码可以合入上游,但如适用,优先放入third-party区域。

仓库中对此已有清晰的实践佐证:第三方代码统一收拢在 src/third-party(如 inih、libpng、lzma、sqlite3、zlib、discord-rpc 等),并在 res/licenses 下保存了各第三方组件的许可文本(如 inih.txt、rapidjson.txt 等)。mGBA 自身源文件则普遍带有 MPL 2.0 的版权头,例如 include/mgba/core/core.h 与 src/core/version.c.in 开头均为 “This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0”。

因此,在提交 PR 前请先确认:你的代码是否可被 MPL 2.0 授权?若是 GPL 衍生代码,它只能作为外链模块存在,不能进入 mGBA 上游代码树。

小结:提交前的最终自查清单

综合 CONTRIBUTING.md 的要点,向 mGBA 贡献之前建议逐项核对:

  1. Issue 提报:附上标题栏版本号(旧版注明具体版本)、操作系统与关键硬件、游戏名称与进入 bug 状态的操作路径,必要时将 savestate 改名.png后上传;
  2. PR 提交:提交信息以组件名开头(如GBA Video:、Core:、Qt:)且内容一致可读,不提交 AI 生成代码;
  3. 编码风格:变量 camelCase、结构体大写开头且不 typedef、枚举与宏全大写、static 变量加_前缀;C++ 类放入QGBA命名空间,成员用m_/s_前缀;
  4. 书写细节:花括号不独占行且单行块也必须加花括号、tab 缩进、头文件保护宏按 C(FILE_NAME_H)与 Qt(QGBA_FILE_NAME)两套规则书写、块语句关键字与括号间留空格、C 用0/bool、C++ 用nullptr、无限循环用while (true);
  5. 许可合规:新代码可接受 MPL 2.0 授权,GPL 代码仅可链接不可合入,宽松许可代码优先放入third-party区域。

遵循这些约定,你的 Issue 将更易被复现、PR 将更易被合并,代码也会与 mGBA 十余年沉淀下来的工程风格保持一致。

  • 游戏开发

【免费下载链接】mgba

mGBA Game Boy Advance Emulator

项目地址:https://gitcode.com/gh_mirrors/mg/mgba
点击查看免费下载

相关推荐

上一篇:react-native-router-flux 状态管理性能未来:超光速内存架构
下一篇:语音识别可视化终极指南:从原始音频到智能分析图表

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询