Programming 版 (精华区)
发信人: superman (☆风雨无阻☆), 信区: Programming
标 题: [转载] DOS到Windows的 游 戏 移 植(5)
发信站: 紫 丁 香 (Sat Aug 29 07:35:48 1998), 站内信件
【 以下文字转载自 cnprogram 讨论区 】
【 原文由 Young_Yang@bbs.ustc.edu.cn 所发表 】
从DOS 到Windows 的 游 戏 移 植(5)
谭 翁
_________________________________________________________________
Moby Dick 修 订 版
---- 在 本 系 列 文 章 的 前 面 几 篇 中, 笔 者 介 绍 了 一 个 名
为Moby Dick 的 简 单 的DOS 游 戏, 并 且 讨 论 将 其 移 植 到32
位Windows 环 境 下。 现 在, 我 们 要 把 游 戏 操 纵 杆 和 鼠 标 输 入
程 序 加 入 到 该 游 戏 的 两 个 版 本 中。 键 盘 输 入 程 序 仍 旧 保
持 不 变。 本 文 讨 论 前 半 部 分: 游 戏 操 纵 杆 的 实 现。
---- Moby Dick 的DOS 版 本 中 大 部 分 是 普 通 的C。 在 Turbo C++ 3.0
下,DOS 版 不 需 要 修 改 就 可 以 编 译 通 过。 如 果 没 有 使 用
Turbo 工 程 文 件, 一 定 要 关 掉 寄 存 器 变 量。Windows 版 是
Visual C++ 4.0 的 一 个 工 程, 但 是 它 也 适 应 其 它 编 译 器。 对
于 DirectInput 的 方 法(Methods), 它 使 用 了 C++ 的 调 用, 而 其 它
情 况 下 都 是 不 使 用 类 的。
---- 如 果 计 算 机 连 接 着 游 戏 操 纵 杆,Moby Dick 的 Windows 版 会
自 动 允 许 使 用 它, 除 非 在 Settings 菜 单 中 设 置 为 使 用 鼠 标
移 动。 实 际 上Windows 有 两 个 不 同 的 鼠 标 接 口, 要 看 编 译 期
间 是 否 定 义 了 USE_DIRECTINPUT。( 本 篇 文 章 所 提 供 的 编 译 版
本 没 有 使 用 DirectInput; 如 果 希 望 添 加 该 定 义 后 编 译 代 码
, 则 需 要 有 DirectX 2 或 者 DirectX 3 SDK)。 在 第 一 个 接 口 变
量 中, 使 用 了 标 准 的 Windows 函 数 GetCursorPos,Ahab( 船 长) 总
是 移 向 光 标。 在 DirectInput 版 本 中, 船 长 则 根 据 鼠 标 的 移
动 而 移 动, 并 不 考 虑 光 标 的 位 置。
DirectInput
---- 过 去 游 戏 开 发 者 都 尽 量 避 开 Windows, 因 为 他 们 已 经 习
惯 于 DOS 环 境 下 的 执 行 和 控 制, 而 这 些 Windows 是 拒 绝 提 供
的。 动 画 一 直 是 最 大 的 工 作 障 碍, 有 人 认 为 可 以 用
DirectDraw 和 Direct3D 有 效 地 解 决 这 一 问 题, 然 而 这 种 解 决
方 案 又 带 来 了 其 它 的 问 题, 其 中 之 一 就 是 输 入 问 题。
---- 在 今 天 的 实 时 游 戏 中, 帧 的 速 率 一 直 增 加, 要 求 快 速
地 反 应 玩 家 的 动 作。DirectInput 试 图 满 足 这 一 直 接 读 取 键
盘、 鼠 标 和 游 戏 操 纵 杆 的 需 求, 它 的 做 法 是 在 保 持 了 基
于 Windows 应 用 程 序 的 设 备 无 关 特 性 的 前 提 下, 让 应 用 程
序 在 尽 可 能 低 的 级 别 上 读 取 这 些 设 备。
---- DirectX 3 SDK 是 第 一 个 包 含 DirectInput 的 DirectX 版 本, 它
是 在 1996 年 9 月 发 行 的。DirectInput 实 际 上 不 是 DirectX 2 SDK
的 组 成 部 分, 同 样 也 不 是 它 的 前 辈--Windows 95 Game SDK 的 组
成 部 分。 在 那 些 版 本 中,DirectInput 只 是 由 在 标 准 Windows 应
用 程 序 编 程 接 口(API) 中 的 游 戏 操 纵 杆 服 务 组 成, 除 此 之
外 还 包 括 控 制 面 板 中 的 设 置 功 能 及 可 用 于 允 许 支 持 数 字
游 戏 操 纵 杆 的 驱 动 模 式。DirectX 3 扩 展 了 DirectInput 的 范 围
, 使 它 包 含 了 有 关 鼠 标 和 键 盘 的 基 于 COM 的 API。
---- 顺 便 说 一 下,DirectInput 提 供 的 新 的 键 盘 服 务 具 有 一 些
优 点, 要 优 于 在 Moby Dick Windows 的 第 一 个 版 本 中 曾 使 用 过
的 GetAsyncKeyState。 新 的 功 能 包 括 读 取 所 有 的 键, 而 不 仅 仅
是 那 些 具 有 实 际 键 码 的 键, 并 且 能 够 为 多 线 程 设 置 事 件
对 象(event objects)。 但 是 目 前,Moby Dick Windows 仍 将 使 用
GetAsyncKeyState, 因 为 它 在 实 时 读 取 键 盘 时 还 是 令 人 满 意
的。
对 游 戏 操 纵 杆 编 程
---- 在 DirectInput 中, 术 语“ 游 戏 操 纵 杆”(joystick) 也 同 样
包 含 游 戏 把 手(game pads)、 飞 行 操 纵 杆(flight yokes) 和 踏
板 系 统(pedal system) 以 及 类 似 的 设 备, 本 文 使 用 这 一 术 语
时, 同 样 包 含 这 些 设 备。
---- 读 取 游 戏 操 纵 杆 既 可 以 通 过 Windows 消 息, 也 可 以 通 过
轮 询。 对 于 前 者, 窗 口 可 以 用 joySetCapture 来 捕 获 游 戏 操 纵
杆, 当 游 戏 操 纵 杆 移 动 或 按 钮 按 下 时, 就 会 通 知 窗 口。 这
样 就 可 能 把 游 戏 操 纵 杆 变 成 象 鼠 标 那 样 的 指 示 设 备: 每
次 操 纵 杆 的 角 度 发 生 变 化 时, 用 户 就 可 以 在 屏 幕 上 移 动
指 针。 然 而,Moby Dick 更 关 心 每 次 经 过 游 戏 循 环 时 游 戏 操
纵 杆 的 位 置, 而 不 是 游 戏 操 纵 杆 的 实 际 移 动, 所 以 需 要
使 用 joyGetPosEx 进 行 轮 询, 而 不 是 监 视 消 息 队 列。
---- 不 使 用 joySetCapture 的 另 外 一 个 原 因 是 操 纵 杆 的 信 息
受 到 了 很 大 的 限 制, 仅 支 持 三 个 轴 方 向( 例 如, 左- 右、
前- 后 和 阀 门(throttle)) 和 四 个 按 钮。 像Microsoft Sidewinder
3D Pro 这 样 的 现 代 输 入 设 备 有 8 个 按 钮、 一 个 point-of-view
hat 和 四 个 轴 方 向 的 移 动( 包 括 一 个 阀 门 滑 块 和 一 个 在 操
纵 杆 上 的 拧 转(twisting) 移 动), 这 显 然 是 无 法 满 足 要 求
的。 对 于 最 新 的 游 戏 操 纵 杆 和 游 戏 把 手, 则 需 要
joyGetPosEx 的 威 力, 它 具 有 返 回 32 个 按 钮、6 个 轴 方 向 以 及
POV hat 的 能 力, 除 此 之 外 还 完 全 支 持 数 字 和 模 拟 设 备。
---- API 参 考 建 议 使 用 过 去 的 游 戏 操 纵 杆 设 备 函 数
joyGetPos, 只 能 有 三 个 轴 方 向 和 四 个 按 钮。 确 实,JoyGetPos
实 现 起 来 非 常 简 单, 但 是 joyGetPosEx 可 以 与 所 有 的 游 戏 操
纵 杆 一 起 工 作, 功 能 更 强。
---- 要 在 程 序 中 包 含 扩 展 的 游 戏 操 纵 杆 服 务, 需 要 链 接
WINMM.LIB , 且 要 包 含 MMSYSTEM.H。
检 测 游 戏 操 纵 杆
---- 要 检 测 游 戏 操 纵 杆, 只 要 使 用 JOYSTICKID1 作 为 参 数 调
用 joyGetPosEx 即 可:
JOYINFOEX joyInfoEx;
ZeroMemory(joyInfoEx, sizeof(joyInfoEx);
joyInfoEx.dwSize = sizeof(joyInfoEx);
BOOL JoyPresent = (joyGetPosEx
(JOYSTICKID1, &joyInfoEx) == JOYERR_NOERROR);
---- 如 果 游 戏 操 纵 杆 没 有 被 正 确 地 安 装 在 Windows 中, 或 者
没 有 被 插 在 计 算 机 上, 函 数 将 返 回 一 个 错 误( 非 零)。
---- 注 意: 就 像 许 多 其 它 的 DirectX 函 数 一 样, 必 须 让
joyGetPosEx 知 道 它 需 要 填 补 的 结 构 有 多 大, 这 会 使 人 感 到
烦 恼, 但 对 于 软 件 的 向 上 兼 容 是 必 需 的。
---- 游 戏 软 件 开 发 者 不 需 要 游 戏 操 纵 杆 配 置 校 准 的 功 能
, 因 为 这 是 用 户 的 责 任, 用 户 可 以 在 控 制 面 板 下 选 择 游
戏 操 纵 杆 和 配 置 校 准。 如 果 开 发 者 想 在 游 戏 菜 单 里 给 用
户 提 供 这 样 一 个 机 会, 只 要 调 用 控 制 面 板 的applet 即 可:
---- WinExec("control joy.cpl", SW_NORMAL);
“ 死 区”(Dead Zone)
---- 在 Moby Dick MS-DOS 中, 笔 者 为 了 在 X 轴 和 Y 轴 中 心 的 周
围 创 建 一 个“ 死 区”, 而 做 了 一 些 计 算。 如 果 没 有 这 个 区
域 的 话, 要 把 船 沿 一 个 轴 方 向 移 动 几 乎 是 不 可 能 的。 因
为 游 戏 操 纵 杆 在 向 另 一 个 轴 方 向 上 稍 有 偏 差 就 会 导 致 船
斜 行。
---- joyGetPosEx 的JOY_USEDEADZONE 标 志 扩 展 了 游 戏 操 纵 杆 的 不
明 确 位 置 的 范 围, 并 且 称 这 一 范 围 为 死 区。 游 戏 操 纵 杆
驱 动 程 序 将 对 在 这 一 死 区 中 的 所 有 位 置 返 回 一 个 常 数 值
。
---- 创 建 死 区 须 注 意 以 下 要 点:
* 必 须 在 注 册 表( 在 REGSTR.H 中 定 义 的 键 下) 中 设 置 死 区
界 限, 并 且 通 过 调 用 joyConfigChanged 来 通 知 系 统。
* 计 算 死 区 所 返 回 的 常 数 值。 其 可 行 的 一 种 方 法 是 将 死
区 的 范 围 设 置 成 与 整 个 游 戏 操 纵 杆 的 控 制 范 围 大 小
相 同, 读 取 轴 的 位 置, 然 后 将 死 区 重 新 设 置 成 实 际 想
要 设 置 的 大 小。
* 关 掉 程 序 时, 应 确 保 恢 复 注 册 表 的 原 始 值, 因 为 其 它
应 用 程 序 可 能 希 望 它 是 默 认 值。
---- 在 Moby Dick Windows 中 的 计 算 方 法 与 在 MS-DOS 版 本 中 一 样
。
使 用Throttle
---- 笔 者 在 Moby Dick Windows 中 给Ahab 的 船 上 添 加 了 一 个
throttle, 这 一 方 面 是 为 了 更 有 趣, 另 一 方 面 可 以 显 示 读
取 游 戏 操 纵 杆 的 控 制 是 非 常 简 单 的, 它 和 任 何 一 个 有 第
三 轴 方 向 或Z 轴( 除 X 轴 和 Y 轴 之 外) 的 设 备 一 起 工 作。 一
般 第 三 个 方 向 的 轴 是 通 过 装 在 底 部 上 的 滑 块 或 轮 子 来 控
制 的。
---- 获 得 throttle 信 息 的 方 法 如 下:
JOYCAPS joyCaps;
JOYINFOEX joyInfoEx;
ZeroMemory(joyInfoEx, sizeof(joyInfoEx);
// 看 一 个 throttle 是 否 可 用
joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps));
BOOL JoyHasThrottle = (joyCaps.wCaps & JOYCAPS_HASZ);
// 如 果 可 用, 读 其 位 置
if (JoyHasThrottle)
{
joyInfoEx.dwSize = sizeof(joyInfoEx);
joyInfoEx.dwFlags = JOY_RETURNZ;
joyGetPosEx(JOYSTICKID1, &joyInfoEx);
}
---- joyInfoEx.dwZpos 提 供 的 就 是 throttle 的 位 置, 可 以 从
joyCaps 的 wZmin 和 wZmax 区 域 中 计 算 出 它 的 相 对 位 置。
---- 另 外, 可 以 通 过 将JOY_RETURNZ 与 其 它 标 志 相 结 合( 使 用
“or” 操 作 符), 从 而 只 用 一 个 单 独 的 调 用 就 可 获 得 操 纵
杆 的 位 置、 按 钮 状 态 等 信 息。
---- 除 了 X、Y 和 Z 轴 以 外, 还 有 其 它 三 个 轴 可 以 进 行 监 控
:R( 用 于 舵(Rudder))、U 和 V。 这 些 方 向 适 用 于 脚 踏 板、 旋
转 游 戏 操 纵 杆 和 其 它 各 种 不 同 的 滑 块、 旋 钮、 和 标 度 盘,
但 不 包 括 POV hat, 它 的 位 置 返 回 在 JOYINFOEX 结 构 的 dwPOV 区
域 中。
_________________________________________________________________
--
※ 来源: 中国科大BBS站 [bbs.ustc.edu.cn]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: poster.hit.edu.c]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:211.690毫秒