不要使用“固定模式编号”(例如模式 0x0118),因为该模式可能不受支持,如果支持,它可能与您所期望的完全不同,因为“固定模式编号”已被弃用约 25几年前的 VBE 版本 2。
考虑到这一点,基本步骤是:
a) 使用“BIOS Int x010, function 0x1A (Get Display Combination Code)”检查计算机是否支持任何类型的视频。如果它是没有任何视频卡的服务器,那么设置视频模式是没有意义的。如果视频卡是古老的 EGA,那么使用 VBE 也是没有意义的。
b1) 使用“VBE function 0x00 (Return VBE Controller Information)”获取有效视频模式编号列表。如果此功能不起作用,则退回“仅古代VGA”或放弃(假设没有显卡,即使有)。
b2) 对于列出的每个模式编号;使用“VBE 函数 0x01(返回模式信息)”来确定模式是什么。理想情况下;你会过滤掉你的代码不支持的任何东西(例如时髦的旧“16色平面”模式,任何需要超过64 KiB的视频RAM但不支持LFB的东西,任何使用YUV而不是RGB的东西,.. .) 同时创建一个可能性列表。如果此功能不起作用,请跳过视频模式。注意:您还需要跟踪“VBE 版本号”(来自 VBE 控制器信息)并使用它来理解“VBE 函数 0x01(返回模式信息)”返回的信息(例如,确定显卡应该返回一些仅适用于更高版本的 VBE 的信息)。
b3) 高级/可选步骤。在创建可能的视频模式列表时;您可能希望与显示器中的信息进行交叉引用,并尝试过滤掉显示器不支持的视频模式。注意VBE返回的视频模式可能显卡支持,显示器不支持;所以除非你检查你不能保证任何东西(640 * 480视频模式除外)都会真正起作用。警告:解析 EDID 是可怕的(主要是因为他们试图尽可能多地打包,为不同的视频时间提供几种不同的格式,其中一些需要你自己的查找表);并试图将“模式计时”(由监视器报告,包括刷新率等)与“视频模式”(由 VBE 使用,没有任何计时/刷新信息)匹配并不是一门精确的科学。
b4) 在您获得完整的视频模式列表后(根据您的操作系统支持的内容以及显示器支持的内容进行过滤);使用某种东西来确定哪种模式是“最佳”模式。这可能比您想象的要复杂得多(例如,计算显示器支持该模式的概率、显示器对视频模式的喜爱程度/它与显示器的原始分辨率的匹配程度、操作系统对性能模式的喜爱程度原因,以及视频模式与用户偏好的接近程度(如果有的话);然后进行某种计算,将所有单独的因素组合成一个视频模式的最终得分;并选择最终得分最高的视频模式)。注意:如果列表为空,请退回到可怕的旧 VGA 模式(例如
c) 使用“VBE function 0x02 (Set Mode)”设置选择的视频模式。如果此时出现错误,请在可能的视频模式列表中将所选视频模式标记为“borked”,然后返回“步骤 b4”。
d) 设置视频模式成功后:
如果是 8 位索引视频模式,请使用“VBE 函数 0x08(设置 DAC 调色板格式)”,然后使用“VBE 函数 0x09(设置调色板数据)”以已知/合理的方式设置调色板(我更喜欢“2-位红色,3 位绿色,2 位蓝色”调色板)。注意:您希望强制视频卡的 DAC 进入默认的“每通道 6 位”模式,因为并不总是支持更好的每通道 8 位,这样可以避免使用 2 段不同的代码来构建数据的麻烦对于 DAC。
从您之前从“VBE 函数 0x01(返回模式信息)”中获得的信息中提取详细信息(水平和垂直分辨率、帧缓冲区的地址、它是哪种像素格式、像素行之间的字节数等),以便您可以通过此有关您绘图的任何代码的信息。
注意:为了更容易支持许多可能的视频模式(这是使代码在更多不同的计算机上工作所必需的);我建议使用“标准”像素格式(例如,可能是 32-bpp,ARGB)将所有绘图都绘制到 RAM 中的缓冲区,然后在将数据从 RAM 中的缓冲区复制到帧缓冲区。这样一来,您绘制东西的所有代码(线条、矩形、字符、窗口装饰、小猫图片等)只需要关心水平和垂直分辨率。
注意:您需要找到我提到的所有函数的参数和描述,并确保您了解它们所做的一切以及它们返回的所有信息。您可以在线找到所有 BIOS 功能的列表(搜索“Ralph Brown's Interrupt List”),您可以在线找到多个版本的 VBE 规范。