# UEFI_Contra **Repository Path**: water_source/UEFI_Contra ## Basic Information - **Project Name**: UEFI_Contra - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-16 - **Last Updated**: 2026-06-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Contra UEFI > 🎮 在 UEFI 固件环境中运行经典 NES 魂斗罗 — 一个裸金属级的游戏移植实验 **English version: [README_EN.md](README_EN.md)** --- ## 项目概述 这是一个将红白机经典《魂斗罗》(Contra)移植到 **UEFI Shell** 环境的技术实验项目。游戏作为 UEFI 应用程序(.efi 文件)运行,直接通过 GOP(Graphics Output Protocol)渲染画面,无需操作系统支持,仅依赖 UEFI 固件。 项目参考了 [NES Contra US Disassembly](https://github.com/vermiceli/nes-contra-us) 的 6502 汇编源码,在 C 语言层面重建了核心游戏逻辑,精灵图片来源于 NES ROM 中提取的素材。 short1 Snipaste_2026-06-13_08-12-50 Snipaste_2026-06-13_19-18-18 ### 特性 - 🖥️ **裸金属运行** — 在 QEMU + OVMF 固件上直接启动,无操作系统 - 🎨 **GOP 图形渲染** — 双缓冲 256×240 游戏画面,整数缩放至显示分辨率 - ⌨️ **键盘输入** — 方向键移动、Z 射击、X 跳跃、Enter 开始 - 🧩 **NES 架构还原** — 完整移植 super-tile 背景系统、2bpp tile + 调色板渲染、RLE 解压 - 🔫 **6 种武器** — Default / Machine Gun / Fire Ball / Spread / Laser / Barrier - 👾 **敌人 AI** — 士兵、炮塔、Boss 炮台、奔跑者 4 种类型 - 🗺️ **关卡数据** — 13 个屏幕的横向卷轴关卡,含 103 个 super-tile - 💾 **文件系统加载精灵** — 通过 UEFI Simple File System Protocol 从 FAT 磁盘读取 .spr 精灵文件 --- ## 运行截图 > 在 QEMU 中启动 UEFI Shell,输入 `Contra` 即可开始游戏。 Snipaste_2026-06-13_08-12-50 --- --- ## 技术架构 ### 渲染管线(每帧 60fps) ``` PollInput() └─ GameStateMachine[gGameRoutineIndex]() └─ LevelRoutine04(核心游戏逻辑) ├─ UpdatePlayer() ├─ UpdatePlayerBullets() ├─ UpdateEnemies() ├─ SpawnScreenEnemies() └─ UpdateScroll() RenderGame() ├─ ClearGameBuffer(BLACK) ├─ DrawBackground() # Super-Tile → 8×8 NES 2bpp tile 合成 ├─ DrawWeaponItems() ├─ DrawPlayerBullets() ├─ DrawEnemyBullets() ├─ DrawEnemies() ├─ DrawPlayer() ├─ DrawHUD() # 生命数、分数、武器指示 └─ ScaleAndPresent() # 整数缩放 + GOP Blt ``` ### NES 图形三层架构 | 层级 | 单位 | 尺寸 | 说明 | |------|------|------|------| | Pattern Table | Tile | 8×8 像素 | 2bpp 格式(16 字节/tile),4 色调色板 | | Super-Tile | 4×4 Tiles | 32×32 像素 | 16 字节索引,4 象限独立调色板 | | Screen | 8×7 Super-Tiles | 256×224 像素 | RLE 压缩存储,展开后 56 字节 | ### 游戏状态机 ``` Game Routines (7 状态) 00 → 01 → 02 → 03 → 04 → 05 ←→ 06 Logo 选择 Demo 闪屏 清空 核心 结局 Level Routines (11 子状态, 在 Game Routine 05 内) 00 → 01 → 02 → 03 → 04 ←→ 05 → 06/07 → 08 → 09 → 0a 加载 显示 闪烁 绘制 核心 过关 GAMEOVER Boss死 序列 延迟 ``` ### 碰撞检测 基于 tile 索引的 4 级碰撞码: - **Code 0** — 空(自由通过) - **Code 1** — 地板(可站立、可穿墙跳下) - **Code 2** — 水面(不可跳跃、下半身隐藏) - **Code 3** — 固体(完全不可穿透) --- ## 快速开始 ### 前置依赖 - **Windows 10/11** + **Visual Studio 2019** - **NASM** — 汇编器 - **QEMU** — 用于运行测试 - **Python 3.x** — 用于数据提取和精灵转换工具 ### 编译步骤 # 2. 转换精灵图片(PNG → .spr) cd tools python png_to_spr.py cd .. # 3. 编译 UEFI 应用程序 cd ../edk2 export WORKSPACE="$(pwd)" export EDK_TOOLS_PATH="$WORKSPACE/BaseTools" export NASM_PREFIX="/c/Program Files/NASM/" export VS2019_PREFIX="/c/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.29.30133/" export WINSDK10_PREFIX="/c/Program Files (x86)/Windows Kits/10/" export PATH="$NASM_PREFIX:$WORKSPACE/BaseTools/Bin/Win64:$VS2019_PREFIX/bin/Hostx64/x64:$PATH" export PYTHONUTF8=1 export PYTHONPATH="$WORKSPACE/BaseTools/Source/Python" python BaseTools/Source/Python/build/build.py \ -p EmulatorPkg/EmulatorPkg.dsc \ -m EmulatorPkg/Application/ContraGame/ContraGame.inf \ -a X64 -t VS2019 -b DEBUG # 4. 部署并测试 cp Build/EmulatorX64/DEBUG_VS2019/X64/Contra.efi ../contra/qemu_test/ cd ../contra/qemu_test qemu-system-x86_64 \ -drive if=pflash,format=raw,file=OVMF_CODE.fd,readonly=on \ -drive file=fat:rw:.,format=raw \ -net none -m 256 -vga std 在 UEFI Shell 中输入 `Contra` 即可运行。 --- ## 操作说明 | 按键 | 功能 | |------|------| | ← → | 水平移动 | | ↑ ↓ | 瞄准方向 / 菜单选择 | | Z | 射击 | | X | 跳跃 | | Enter | 开始 / 确认 | | P | 暂停 | | ESC | 退出游戏 | --- ## 设计约束与取舍 本项目力求在 UEFI 环境下忠实还原 NES 魂斗罗的核心体验,同时做出以下务实的取舍: - **不包含音频** — UEFI 环境下音频驱动复杂度高,且 QEMU 模拟效果有限 - **静态内存分配** — 所有游戏数组编译期定长,避免运行时动态分配带来的碎片和失败 - **整数缩放** — 256×240 游戏画面通过 2×/3× 整数倍缩放至现代分辨率,避免非整数缩放导致的像素锯齿 - **精灵 PNG 预转换** — 精灵图片在编译前通过 Python 脚本转换为 `.spr` 二进制格式,运行时通过 UEFI 文件系统协议加载,避免将图片嵌入 .efi 导致体积膨胀 - **固定点物理** — 使用 INT32 8.8 定点数格式,避免浮点运算,确保跨平台精度一致 --- ## 代码统计 | 类别 | 行数 | |------|------| | C 源代码 (.c) | ~3,200 | | 头文件 (.h) | ~1,900 | | 关卡数据 | ~650 | | Python 工具 | ~1,800 | | **总计** | **~7,500** | --- ## 参考资源 - [NES Contra US Disassembly](https://github.com/vermiceli/nes-contra-us) — 6502 汇编反编译项目 - [Retro Game Internals: Contra Levels](https://tomorrowcorporation.com/posts/retro-game-internals-contra-levels) — Allan Blomquist 的关卡结构深度解析 - [NESDev Wiki](https://www.nesdev.org/wiki/) — NES 图形(PPU)、调色板、Nametable 等技术规范 --- ## 开源许可 本项目代码以 **MIT License** 授权发布。 NES 反汇编参考代码及精灵图片来源于 [nes-contra-us](https://github.com/vermiceli/nes-contra-us) 项目,版权归原始权利人所有。 --- ## 鸣谢 - [vermiceli](https://github.com/vermiceli) 及贡献者 — 完整的 NES 魂斗罗反汇编工程,为移植提供了精确的游戏逻辑参考 - UEFI / TianoCore 社区 — EDK2 开发框架和 OVMF 固件 - QEMU 项目 — 强大的开源模拟器,使开发和测试成为可能