Skip to content

Repository files navigation

《仙剑奇侠传 DOS 版》— Rust 移植

简介

1995年7月10日出品(故常被称作“仙剑95版”),由大宇资讯狂徒创作群制作,是影响了整整一代玩家的游戏大作。感人的剧情、动情的音乐、还有那优雅的诗词至今仍让老一辈的玩家难以忘怀。游戏的主角李逍遥、赵灵儿、林月如、阿奴,也成了游戏界的明星人物。

本仓库是该 DOS 版游戏引擎的 完整 Rust 移植(自 SDLPAL 的 C 源码移植,PAL_CLASSIC 经典模式),直接运行 pal/ 目录中的原版游戏数据,不再需要 DOSBox。游戏以 1280×720 输出;原版 320×200 游戏画面保持正确比例,开场菜单使用增强的高清美术资源。

This is a complete Rust reimplementation of the PAL (Legend of Sword and Fairy, DOS version) game engine, ported from SDLPAL and running the original game data shipped in pal/ — no DOSBox required. The engine presents at 1280×720, preserves the original 8:5 gameplay geometry in a 1152×720 viewport, and uses an enhanced HD art resource for the opening menu. Native gameplay frames are upscaled by the same FP16 neural mega-kernel as the web build through wgpu (Vulkan on supported Linux/Windows systems, Metal on macOS). Set RUSTPAL_DISABLE_GPU_UPSCALE=1 to use nearest-neighbor scaling.

战斗演示 / Battle Demo

一场完整的经典回合制战斗(出招菜单 → 选择目标 → 攻击特效 → 敌方反击 → 战斗结算):

全程自动通关录像 / Full Autoplay Run

基于本地控制 API 无窗口自动通关全程(约 2 小时 20 分,YouTube):

全程自动通关录像 / Full Autoplay Run

自动游玩录制 / Autoplay recording

examples/autoplay.rs 让引擎自己玩并录成 1280×800 的视频(经神经网络放大, 含原版 OPL 音乐与音效):

cargo run --release --example autoplay -- out 300 30   # 输出 out/autoplay.mp4
cargo run --release --example autoplay -- record out 300   # 只录制
cargo run --release --example autoplay -- encode out 30    # 只编码(可重复调参)

它给引擎装上一副“合成键盘”(Engine::autopilot,在引擎读键盘的地方按/放键)和 一台离线混音器(Mixer::offline,按引擎时钟渲染采样),因此开场动画、菜单、剧情 对话、战斗全部走正常流程——没有任何快进或桩实现。

录制分两步:引擎时钟就是真实时钟(Engine::ticks),而放大网络每帧要几十毫秒, 边玩边放大会让画面落后于真实时间、而音乐不会,于是画面相对声音变成慢动作。所以 record 只实时转储 320×200 原始帧、每帧的引擎时刻和 PCM 音频;encode 事后 不赶时间地把每个不同的帧送进放大网络,按引擎时刻做 sample-and-hold 重采样到固定 帧率,再与音频合成 mp4。中间文件保留着,改帧率重新 encode 不必重玩一遍。

The engine plays itself and records the result (with the original OPL music and sound effects): a synthetic keyboard presses keys wherever the engine reads the real one, and an offline mixer renders audio in lockstep with the engine clock, so every dialog, menu, script and battle runs the normal way.

Recording is split in two because the engine clock is wall clock and the neural network costs tens of milliseconds a frame: upscaling while the game runs would put the picture into slow motion against music that kept its pace. So record dumps raw 320×200 frames, their engine ticks and the audio in real time, and encode comes back afterwards with no deadline to upscale each distinct frame, resample to a constant frame rate and mux. Requires ffmpeg and a GPU with shader-f16; the intermediates are kept so a re-encode is cheap.

运行 / Running

cargo run --release

操作:方向键移动,空格/回车 调查·确认,Esc 菜单;战斗中 R 连续攻击、A 自动、D 防御、E 物品、W 投掷、Q 逃跑、F 仙术、S 状态。

本地控制 API / Local control API

原生版可选择启用仅监听回环地址的 HTTP 控制接口,供自动化程序读取当前 320×200 游戏画面并发送与真实键盘相同的按键事件:

cargo run --release -- --ui-driver --offscreen

curl http://127.0.0.1:8765/v1/status
curl http://127.0.0.1:8765/v1/frame.png -o frame.png
curl -X POST http://127.0.0.1:8765/v1/input/confirm/tap
curl -X POST http://127.0.0.1:8765/v1/input/up/press
curl -X POST http://127.0.0.1:8765/v1/input/up/release

默认地址为 127.0.0.1:8765,也可使用 --ui-driver=127.0.0.1:PORT 或环境变量 RUSTPAL_UI_DRIVER 指定。 --offscreen 会继续渲染和捕获画面,但从一开始就不显示原生游戏窗口, 同时禁用音乐和音效。也可分别使用环境变量 RUSTPAL_OFFSCREENRUSTPAL_DISABLE_AUDIO,或通过 --mute 仅关闭声音。 接口拒绝监听非回环地址。可用按键名称:updownleftrightmenuconfirmspacepage_uppage_downhomeendrepeatautodefenduse_itemthrow_itemfleeforcestatus

完整接口说明、自动游玩流程和本次无窗口运行的进度截图见 Offscreen Autoplay

自动进入开场剧情 自动离开初始房间 自动探索客栈

浏览器版 / Running in the browser (wasm)

在线试玩 / Play online: https://madeye.github.io/Legend-of-Sword-and-Fairy/ (由 GitHub Actions 自动构建部署,见 .github/workflows/pages.yml

整个同步引擎原样运行在 Web Worker 中:画面输出到 canvas,键盘输入与 音频采样通过 SharedArrayBuffer 环形缓冲传递(音乐由 AudioWorklet 播放), 存档保存在 localStorage。

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli
./web/build.sh          # 构建 wasm 包到 web/pkg/
python3 web/serve.py    # 本地服务器(带 SharedArrayBuffer 所需的 COOP/COEP 头)
# 打开 http://127.0.0.1:8080/web/

触屏设备(手机/平板)会显示虚拟按键:左下方向键,右下 確認/取消/連擊, 可完整游玩(战斗菜单均可用方向键 + 確認/取消 操作)。

注意:浏览器要求页面有一次点击/按键后才会开始播放声音。SharedArrayBuffer 需要跨源隔离:自建服务器请设置 Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp 响应头;无法自定义响应头的 静态托管(如 GitHub Pages)由页面内置的 coi-serviceworker.js 代为注入 (首次访问会自动刷新一次)。

支持平台

macOS / Linux / Windows(winit + pixels 渲染,cpal 音频),以及现代浏览器 (wasm32 + Web Worker + SharedArrayBuffer + AudioWorklet)。

架构 / Architecture

  • src/game_loop.rsEngine 核心:全部游戏状态、winit/pixels 720p 视频、帧循环、调色板渐变与转场
  • src/native_upscale.rs — 原生 FP16 神经网络放大器;复用 pixels 的 wgpu 设备并在 Vulkan/Metal 上执行与 WebGPU 相同的 18 层 mega-kernel
  • 各子系统以 impl Engine 扩展:scene(地图与精灵渲染、移动碰撞)、script(完整脚本解释器)、playui/uigame/itemmenu/magicmenu(对话与菜单)、battle/fight/uibattle(经典回合制战斗)、endingrngplay(过场动画)
  • 数据层:mkf(MKF 档案)、yj(YJ_1/YJ_2 解压)、mapglobal(游戏数据与 DOS 存档格式)、text/font(Big5 文本 + 原版 WOR16 字库)
  • 音频:opl(DOSBox DBOPL 移植)、rix(RIX 音乐)、voc(音效)、audio(混音)

移植保真度 / Fidelity

  • YJ_1 解压与 C 实现在全部 1159 个压缩块上逐字节一致
  • OPL/RIX 音乐渲染与 C++ 原实现在 20 首曲目 × 30 秒上逐字节一致
  • 画面经无头渲染逐帧验证(examples/ 内含验证工具)
  • 1280×720 原生输出;1152×720 游戏视口避免把原版 8:5 画面拉伸成 16:9
  • ImageGen 增强的开场菜单背景保留实时文字、选择颜色和原版调色板淡入淡出
  • 97 个单元测试 + 4 个端到端集成测试(cargo test,需要 pal/ 数据)

版权声明 / Copyright Notice

《仙剑奇侠传》为大宇资讯股份有限公司(Softstar Entertainment Inc.)的版权作品及注册商标。pal/ 目录中的原版游戏数据(图像、音乐、文本、剧本等)版权归大宇资讯及其关联公司所有。本仓库仅供技术学习、研究与怀旧交流之用,禁止任何商业用途;如版权方认为本仓库损害其权益,请联系删除。

引擎代码自 SDLPAL 移植,遵循其 GPL-3.0 开源协议。

Legend of Sword and Fairy (PAL) is a copyrighted work and registered trademark of Softstar Entertainment Inc. The original game data in pal/ (graphics, music, text, scripts, etc.) is the property of Softstar and its affiliates. This repository exists solely for technical study, research, and nostalgia; any commercial use is prohibited. If the rights holder believes this repository infringes on their rights, please contact us for removal. The engine code is ported from SDLPAL and follows its GPL-3.0 license.

截图 / Screenshots

About

A complete Rust port of the PAL (Legend of Sword and Fairy) DOS engine, playable natively or in the browser via wasm

Resources

Stars

163 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages