VGA10H如何编制RPG游戏

汇编语言实现篇
VGA的绘图模式中,最重要的是模式12和模式13(我想大部分玩家手上已经没有CGA、EGA显示卡了吧)。模式12H采用平面式对应的方法,支持640×480,视频内存起始地址为A0000H,和其它D、E、10H三种模式一样同为16色,只是分辨率有所不同。视频内存地址上,每一个字节代表8个像素,每一位又可对应到颜色平面中同样位置的4位上。当我们要在屏幕上绘出一个点时,就必须将数据分别存放到四个颜色平面中对应的位上。VGA提供了许多存取颜色平面数据的方法,如一次存取4个颜色平面数据或每次只对单一平面操作,哪种方法比较快呢?如果是图像方面的处理,选择第二种较理想;而对于画点方式的作图,第一种更快速一些。
模式13H是VGA卡中唯一可同显256的模式,支持分辨率320×200,视频内存起始地址A0000H,它采用的是线性对应的方法(SVGA的所有256色和真彩都是用这种方法)。线性对应将屏幕上每一点与视频内存地址按顺序一一对应起来,一个点对应一个字节,这样做的好处是:这种对应方式比颜色平面对应方式简单多了,因为我们只需直接对视频内存地址做存取即可,而不必理会颜色平面与内存地址的对应关系。大家不难看出,其实线性对应就是将四个颜色平面的内存串联在一起,而成为一种直线的排列。
MODE 13H模式


MODE13h拥有320×200=64000个像素即64000bytes。MODE 13h的显存从地址A000:0000h开始,到A000:FFFFh结束。这总共有65535bytes,从而使屏幕底部还包含了4个不可见的行。
要往屏幕上写一个像素,须先把段寄存器ES设为A0000h,再计算出该像素的偏移量放入DI,然后向ES:DI写入一个colorbyte(即表示颜色的byte)。偏移量用下式计算:
偏移量 = 320 × y + x
其中x是x坐标值,y是y坐标值。坐标(0,0)位于屏幕的左上角,坐标(319,199)位于屏幕的右下角。下面列出了各个坐标及其相应的偏移量:
(0,0) (1,0) (2,0) (3,0) … … …(319,0)
---------------------------x轴-----------------------------
0 0   1   2   3   … … … 319  
1 320   321   322   323   … … … 639   (319,1)
2 640   641   642   643   … … … 959   (319,2)
. .   .   .   .   … … … .
. .   .   .   .   … … … .
. .   .   .   .   … … … .
199 63680 63681 63682 63683 … … … 63999

(0,199) (1,199) (2,199) (3,199) … … … (319,199)
y轴
以下是一个写一个色点程序
例子1、 code segment
         assume cs:code
         main :      Mov ax,0a000h
Mov es,ax
                ;******以下是模式选择
Mov ah,0h
Mov al,13h
Int 10h
;************画一个点*********************
Mov al,45h;色点
Mov di,0h;显存地址(对应屏幕上位置)
stosb
;*******************控制程序
mov ah,1
int 21h
      mov ah,4ch
      int 21h
;*****************************************
code ends
end main

    在这里我们画出了一个彩色点,位置在显存的A000(ES):0(DI)处,对应在屏幕的左上角上。
    在上述画点的位置,改写后如下(形成一个过渡色的彩色带子)
例子二、code segment
          assume cs:code
             main :     Mov ax,0a000h
Mov es,ax
Mov ah,0h
Mov al,13h
Int 10h
;***************************
mov di,0a000h;      决定显示的位置
mov cx,6;          画一个完整的连续象素条(粉红到深红)
mov al,34;         决定起始颜色
loop_f : inc ax;            颜色值加一
           call xi;          画出一条色带
          loop loop_f
       jmp dos
;********** 一条彩色像素,色点为AL
xi proc;     这个过程为一条320个像素的色线
pushf
push cx
Mov cx,320;   20像素
rep stosb
pop cx
popf
ret
xi endp
;****************************
dos:mov ah,1
int 21h
      mov ah,4ch
      int 21h
;*****************************************

code ends
end main
例子三、一条彩色过渡带(红)

关于颜色
个像素具有什么颜色取决于两个因素:你向屏幕写入的颜色值(0至255)以及该值在调色板中所代表的颜色。调色板共有256个入口(0到255)。调色板中的每一种颜色由3个byte表示,分别代表红、绿、蓝三种颜色。每一个byte值都在0到63之间。值的大小表示了颜色的强度:0表示没有强度,63表示最大强度。这样就有了64的3次方种可能的颜色。
[常见的颜色]
红       绿       蓝        颜色
______________________________
0        0        0        BLACK黑
63       0        0        RED红
20       0        0        DARK RED暗红
0        63       0        GREEN绿
0        0        63       BLUE蓝
63       63       0        YELLOW黄
63       32       0        orANGE橙
63       0        63       PURPLE紫
0        63       63       CYAN青
63       63       63       WHITE白
32       32       32       GRAY灰
10       10       10       DARKGRAY暗灰
MCGA-mode 13h总是以相同的调色板开始(即0表示黑,1表示蓝,等等)。但要自己改变调色板是很容易的。通过向3c8h和3c9h端口写入适当信息,我们就可以改变调色板。这并没有看上去那么难。你只要向3c8h端口写入你希望改变的起始颜色的索引值,再向3c9h端口写入红、绿、蓝的值就可以了。向3c9h写入了这三个colorbyte后,索引会自动递增。
例子四、设置写模式色彩
MOV DX,3CEH;图形控制索引寄存器
     MOV AL,5;模式索引
     OUT DX,AL
     MOV DX,3CFH;图形控制数据寄存器
     POP AX;存在这里的颜色值
     OUT DX,AL
         MOV DX,3CEH
例子五、
         xi proc;这个过程为一条120个像素的色线
pushf
push cx
mov di,640*6;     这是指从那一行开始(第6行)
mov al,45h;       颜色点
Mov cx,120;120像素的一段线
rep stosb
pop cx
popf
ret
xi endp
例子六、一个彩色渐变的窗口
code segment
   assume cs:code
       main :
Mov ax,0a000h
Mov es,ax
Mov ah,0h
Mov al,13h
Int 10h
;***************************
mov di,320*5;决定显示的位置
mov cx,30;画一个完整的连续象素条(粉红到深红再到。。。)
mov al,35;决定起始颜色
loop_f : inc ax;颜色值加一
           call xi;画出一条色带
    call tt
    add di,320-120;对称呀
loop loop_f
   call tt
  
        jmp dos
;********** 一条彩色像素,色点为AL
xi proc;这个过程为一条320个像素的色线
pushf
push cx
Mov cx,120;120像素
rep stosb
pop cx
popf
ret
xi endp
;****************************
dos:
mov ah,1
int 21h
      mov ah,4ch
      int 21h
;*****************************************
tt proc;定时器
pushf
push ax
push dx
push cx
mov cx,0ffffh
ttt:mov dx,0fffh
tttt:dec dx
cmp dx,0
jnz tttt
loop ttt
pop cx
pop dx
pop ax
popf
ret
tt endp
;************
code ends
end main
例子六:斜线
mov di,320*5+100;决定显示的位置
mov cx,30;画一个完整的连续象素条
mov al,35;决定颜色
loop_f :   call xi;画出一条色带
      add di,320
    loop loop_f
          jmp dos
;********** 一个彩色像素,色点为AL
xi proc;这个过程为一个像素
stosb
ret
xi endp
例子七、关于Model 12h的例子
;这是一个 宽度为80(50H,280H)个字节,高为480(1E0H)个像素
code segment
   assume cs:code
       main :
      Mov ax,0a000h
Mov es,ax
Mov ah,0h
Mov al,12h
Int 10h

;***************************
mov di,640*5+100;决定显示的位置
mov cx,20;画一个完整的连续象素条(粉红到深红)
     MOV DX,3CEH;图形控制索引寄存器
     MOV AL,05H;模式索引
     OUT DX,AL
     MOV DX,3CFH;图形控制数据寄存器
     MOV AX,084H;存在这里的颜色值
     OUT DX,AL
         MOV DX,3CEH

;******************************
loop_f :
           stosb
    call tt
    add di,79
    loop loop_f
        
mov ah,1
int 21h
      mov ah,4ch
      int 21h
;*****************************************
tt proc;定时器
pushf
push ax
push dx
push cx
mov cx,0ffffh
ttt:mov dx,0fffh
tttt:dec dx
cmp dx,0
jnz tttt
loop ttt
pop cx
pop dx
pop ax
popf
ret
tt endp
;************
code ends
end main
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: RPG 游戏 VGA10H
相关日志:
评论: 0 | 引用: 0 | 查看次数: 2206