首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

DOS 遊戲編程二十一條鐵律 (1999 經典重發) :穿越時空的性能優化與工程智慧

     編輯:關於C語言

前言:1999 年的聲音,2024 年依然回響

這篇文章寫於 1999 年 11 月,彼時 DOS 遊戲開發如日中天。雖然平台已逝,但文中關於**性能極致追求、工程權衡、底層思維**的核心觀點,放在現代高性能計算、嵌入式開發、遊戲引擎研發中,**依然閃耀著真理的光芒**。

二十一條鐵律精華重述與現代映照

1. 語言選擇:快、更快、再快

Watcom C/C++ 32 位保護模式 + DOS/4GW 是當時王者。今日映照:**為熱點路徑選擇最接近硬件的語言 (C/C++/Rust/Assembly),業務邏輯用高級語言** — — 混合編程是永恆真理。

2. 專用勝過通用

「通用意味著慢」。**為當前具體問題寫最專用的代碼**,拒絕過度設計。現代術語:**YAGNI (You Aren't Gonna Need It)** + **Data-Oriented Design**。

3. 幀率預算:70 FPS 渲染 → 30 FPS 遊戲邏輯

VGA 70Hz 刷新率,雙緩衝消隱。留給邏輯的時間 < 14ms/幂。今日映照:**預算驅動架構**,Profile-Guided Optimization。

4. 引擎先行:2 個月寫引擎,2 個月寫遊戲,2 個月調試

**「搬數據」是計算機本質**。數據結構、內存佈局、訪問模式決定性能上限。現代術語:**Engine Architecture First**。

5. 拒絕乘除法與浮點數:移位乘法實戰

// 1999 代碼:計算屏幕偏移 = width * y + x
int count_offest(int _width, int x, int y) {
    int mode[17] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536};
    int i, offest = 0;
    for (i=16; i>=0; i--) {
        if (_width >= mode[i]) {
            offest += (y << i);  // 移位代替乘法
            _width -= mode[i];
            if (_width < 1) break;
        }
    }
    return offest + x;
}

今日映照:**整數運算優於浮點,編譯器優化不如算法重寫**,SIMD 內聯函數是現代移位乘法。

6. 美術資源管線:程序員不畫圖,找美工或買素材

PCX/BMP 讀寫器是必備基建。今日映照:**Asset Pipeline 自動化、Texture Atlas、GPU 友好格式 (KTX/ASTC)**。

7. 畫點函數是宇宙基石

無乘法、分辨率自適應的 `point(x,y,color)`。今日映照:**像素著色器、Compute Shader、光柵化器**的核心邏輯同源。

8. 鏤空算法:透明色法 > AND/OR Mask

「每個點少處理一次,你至少能多跳一圈舞」。今日映照:**Alpha Blending 硬件加速、Alpha Test、Alpha To Coverage** — — 算法思想未變,執行單元變了。

9. 雙緩衝非銀彈:跟蹤掃描線 (V-Sync) 才是零閃爍正道

void wait(void) { // 等待垂直回描
    while (inp(0x3DA) & 0x08);
    while (!(inp(0x3DA) & 0x08));
}

今日映照:**`glfwSwapInterval(1)` / `Present(1)` / `VK_PRESENT_MODE_FIFO_KHR`** — — 同步顯示器刷新率是跨時代共識。

10. 主循環 70+ FPS 硬指標

背景、精靈、鼠標、鍵盤 — — 全在一幂搞定。今日映照:**Game Loop 固定時間步、系統解耦、ECS 架構**。

11. 優化迭代 7-10 輪:從 12 FPS 到 70 FPS

「不要用編譯器優化,除非想用戶跑不動」。今日映照:**手工優化關鍵熱點,PGO 輔助,`-O3` 不是萬能藥**。

12-14. 計算每條指令代價:指令級優化

// 從
*(Video+k) = *(p[1]+j); k++;
// 到
*(Video+(k++)) = *(*(p+1)+j); // 減少讀內存、數組轉指針開銷
// 再到:循環展開 10 次,寄存器緩存基址,合併存儲

今日映照:**編譯器輸出檢查 (Godbolt)、內聯汇編、SIMD 向量化、內存訪問模式優化 (SoA vs AoS)**。

15. 判斷語句不省:1 條 `if` 換 100 條指令,血賺

今日映照:**分支預測友好寫法、條件移動指令 (CMOV)、無分支編程**。

16. 防禦性編程習慣:`if (1 == i)` 防賦值誤判斷

今日映照:**編譯器警告 `-Wparentheses`、靜態分析 (Clang-Tidy/Cppcheck)、單元測試覆蓋**。

17. 時鐘中斷驅動:攔截 0x1C,改頻率,Switch/Case 狀態機

void _interrupt Timer() { timer_program(); timer_counter++; Old_Time_Isr(); }
void install_timer(int Hz) { /* 重編程 8253 芯片 */ }

今日映照:**高精度定時器 (HPET)、`timerfd`、`setitimer`、遊戲循環固定步長累加器**。

18. 鼠標驅動:直讀 0x33 端口,自己畫游標

今日映照:**Raw Input API、高 DPI 感知、自定義游標渲染** — — 從不信任系統預設行為。

19. 鍵盤中斷攔截:直掛 0x09,構建掃描碼→ASCII 映射表

今日映照:**`WM_INPUT` / `libinput` / `SDL_Event` — — 繞過系統消息泵獲取原始輸入**。

20. 調試即基建:自製 `debug()` 寫文件,不依賴 IDE

今日映照:**結構化日誌 (spdlog/glog)、分布式追蹤 (Jaeger)、Metrics (Prometheus)** — — 可觀測性是系統內建屬性。

21. 可持續節奏:寫不動了就去玩,熱情耗盡寫不出好遊戲

今日映照:**開發者體驗 (DX)、心理健康、可持續交付** — — 人是核心資產。

跨時代對話:給現代開發者的三個啟示

  1. 性能優化的本質不變:減少內存訪問、消除冗餘計算、利用硬件特性 — — 只換了工具鏈
  2. 工程紀律比技術棧更長壽:專用優於通用、預算驅動設計、自建基建不依賴框架
  3. 底層思維是穿越周期的護城河:理解 CPU/GPU/內存/總線如何協作,才能在任何抽象層做正確決策

結語

肖舸 1999.11.1 於《DOS遊戲編程二十一條》。二十二載光陰,鐵律未銹。願每位追求極致的工程師,都能在自己的時代裡,聽見這聲音的回響。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved