BBS水木清华站∶精华区

 
 
       战   斗   世   家   C 语言讲座                  #5 
 
                                 作者: Lgw Lu 
                                 E-Mail: lgwlu@ms1.hinet.net 
--------------------------------------------------------------- 
 
                   < 写 GAME 利器 - Watcom C/C++ > 
 
前言: 
 
     相信大家玩的很多游戏,大部分都是用 Watcom C/C++ 所写的,我 
  想最大原因因该是它附的一套授权的 32 bits DOS Extender DOS4GW; 
  DOS4GW 让大家进入保护模式的 flat mode 中,可以享受到线性记忆 
  体的方便,以下便介绍一些 Watcom C/C++ 写作技巧。 
  (P.S Runtime 版 DOS4GW 只支援到 32MB memory) 
 
内文: 
 
     首先,我先抱怨一下!! Watcom C/C++ DOS 下竟不附 IDE,且在 
  windows 下的 IDE 实在有够..... 逊!! 附一套 VI 编辑器,也是... 
  唉!! 我觉得它叫 SHELL 程式还比较好,叫 IDE 实在是............ 
  (P.S EDITER 外挂,MAKE,DEBUG,.... 都是 Call 别的程式,它叫 
   IDE ???? 且画面 #@#$!) 
 
     说了一堆离题的东东,现在切入正题!!以下 Watcom C/C++ 简称WC 
 
     (1) 差异 
 
             当你用 WC 32bits 时,首先要有一些 16bits 和 32bits 
         资料型别不同的观念,这样才不会出错. 
 
         16 bits                     32 bits 
 
         char      1 byte            char        1 byte 
         wchar_t   2 bytes           wchar_t     2 bytes 
         int       2 bytes           short int   2 bytes 
         long      4 bytes           int         4 bytes 
                                     long        4 bytes=>注意 
 
         还有在 flat mode 因为是线性记忆体 So 指标都是 near, 
         不要再设啥 far。 
         (P.S 除非是切到 real mode 时用的 pointer) 
         另外,因为线性记忆体,So pointer 位址表示是用 line 方式 
 
         Ex: char *ptr=0xa0000;  // 直接定址,要再用 0xa0000000 
 
         当你在 DOS4GW 下写 ISR 时,它会帮你自动建一 real mode 
         的 ISR,So 不用担心 ISR 写法,照以前写法就可. 
 
         若你想 call real mode 的中断处理程式时,一部份 DOS4GW 
         在 flat mode 下都有相对应程式,如 int 33h,int 10h... 
         但是像 int 21h,或是需要得到一 real mode DATA 时, 
         DOS4GW Runtime 版有支援 DPMI 300h 的功能可供使用,用 
         法 on line HELP 已有!! 
 
     (2) 组语 
 
             虽然 WC 最佳化做的不错,但还是有人希望能配合 ASM 
         以发挥更大威力,在此提供数种方法. 
 
         1. 编译指令 
 
             由於 WC 不支援线上组语,造成一些不便,So WC 在 10.0 
             以後的版本可以用编译指令来达到相同目的。 
             (P.S. 9.5 版只能用来写机械码.........) 
 
             附带说明 WC 支援 register 及 stack 两种方式传递参 
             数,在以後的□例中我会指明是用哪种方式,记得一点 你 
             安装 WC 时最好两种方式的 LIB 都装上, 如此适用性会 
             较佳!! 
 
             /* REGISTER 方式 */ 
 
             void setvmode(int);    // 记得要宣告 
             #pragma aux setvmode = \ 
                " int 0x10 " , \ 
                parm[eax] \ 
                ^^^^^^^^^^ 用 eax 传参数 
 
                若有回值用 value [ebx];  ==> 记得加 ; 
                                  ^^^ 用你想用的 
 
             这样 WC 就会在程式这段加入机器码,所以你宣告函式一 
             定要在前一行,不然就找不到函式起始位址. 
 
         2. WASM 
 
             这套是 WC 附的,虽然功能不强,但写 ASM 措措有馀!! 
 
             /* REGISTER 方式 */ 
 
             .C 中 
 
             extern "C" void _setvmode(int); 
 
             #pragma aux _setvmode "*_" parm caller [eax]; 
             // 这行若不写,在此例中也是可以,但不写, 
                参数传递顺序是 eax edx ecx ebx .... 
                且自己要加上底现在 函式名之後,此为 WC register 
                传递格式。 
 
             .ASM 中 
 
              public _setvmode_ 
 
              ; 後面的 _ 是 WC 传 register 参数时必须加的。 
 
               ....... 
               ...... 
              _setvmode_  proc near 
                          int 10h 
                          ret 
              _setvmode_  endp 
              ..... 
 
              ; 在此只列出片段 
              ; 当然任何 ASSMBER 都可用传 STACK 方式,WASM 亦可 
 
 
         3. MASM / TASM 
 
            /* 用 STACK 方式 */ 
 
           .C 中 
 
           // 同一般 C Call ASM 方法,在此不累述 
 
           .ASM 中 
 
           ;MASM                          ;TASM 
 
           .386p                          ideal 
                                          p386 
           model   flat,c                 model flat,c 
 
           .code                          codeseg 
 
           public _setvmode               proc C _setvmode 
                                              arg mode:dword 
           ...... 
           ....                               public _setvmode 
                                              uses  eax 
           _setvmode  proc C 
                      uses eax,mode:dword     mov  eax,mode 
                                              int  10h 
                      mov  eax,mode           ret 
                      int  10h            endp 
                      ret                  ...... 
           _setvmode  endp                  ..... 
           .....                           .... 
           ... 
 
     好了!! 小弟眼睛又开始酸了,暂时就写到这,以後会再谈到 WC 的 
  ,若还有问题,老话一句 - " 拿信来砸我吧 !! " 
 
预告: 
     下篇将举出使用巨集的好处及注意事项!! 记得 " 收看 " ... 
  < 巨集之评析 > 
 
--------------------------------------------------------------- 
 
                  <<< 本文版权属於作者 >>> 
     本文章可自由引用,拷贝,传阅,但需保持本文章之完整性,从标题 
  到最後版权宣告,且不能用来做商业用途!! 
 
     若有任何问题,或是错误之处,欢迎来信批评指教!! 谢谢!! 
 
 
 
 

BBS水木清华站∶精华区