注册 登录
编程论坛 汇编论坛

今天刚学完王爽汇编

热心网友 发布于 2020-03-11 11:25, 11831 次点击
学完了以后,感觉更想探索16位DOS系统的编程了,尤其是DOS中的图形编程,求各位高手分享DOS下的图形编程的书籍,最好是关于DOS开发游戏的
20 回复
#2
Valenciax2020-03-12 19:18
楼主要写什么类型游戏?

受限于显卡驱动,dos下最多只能运行SVGA模式,就是1024x768,256色,除了INT10H那几个绘点函式,
系统没有任何支援,音乐鼠标什么的,通通由作者一手包办,要做一个像样的游戏其实是烦之又烦..

当然,写些简简单单还是可以的,权作练手...
#3
热心网友2020-03-13 10:24
就是往显卡里写界面的那种,但是网上资源太少了
#4
Valenciax2020-03-13 16:58
DOS的显存分布
0A000H-0B000H 绘图模式
0B000H-0C000H 文字模式

0A000H-0B000H只有区区64K,在不换页的情况下,处理320X200(=64000)最方便,
直接在0A000H:???? 送出图点即可,下面是许久以前,我拿用别的游戏素材,
用汇编写的RPG,只用13H模式(320X200),当然解像是挺粗糙的.
只有本站会员才能查看附件,请 登录

若要求高一些的解像,比如640X480(=307200),除以64K=4.6875,共5页
显存仍然是0A000H-0B000H,输出图点时(比如X,Y=10,110),计算后图点在
第2页(110x640/64K=结果大于1,小于2),就要换到页2,然后再输出经调整的
0A000H:????显存中.

大概就是这样,挺麻煩的不是?

楼主可能有疑问,既然这么烦,为啥不用INT10的绘点函式?
可以是可以的,但计算显示页再输出的编码是烦琐和复杂,但仍比INT10绘点函式快不止10X倍.
同样输出一整个画面,是瞬间和几秒的差异.

换页和设定SVGA模式,可以用IN/OUT,不过DOSBOX不允许,但仍可以用
INT 10H / AX=4F??H 的 VESA SuperVGA BIOS (VBE) 去转换.
可以参考
http://www.
有完整的INT10函式和用法,看看Int 10/AX=4F00h如何操作
#5
热心网友2020-03-13 17:24
听您这么一说,我就算涨知识了
#6
热心网友2020-03-13 17:29
这个int 13h的画图方法能举个例子么
#7
Valenciax2020-03-13 19:49
不是INT 13H,是INT10H,AX=0013H,这里AH=0是设定显示模式,AL=13H(320x200x256色).
找了一下,这里有一个回覆某问题所写的范例,用的正是显示模式13H
只有本站会员才能查看附件,请 登录

程式挺简单的,就是一只蜻蜓,在画面上自由飞行.蜻蜓的图是flybmp.dat,主程式是movfly.exe
可以在这里下载.
链接: https://pan.baidu.com/s/1l6dMhHnft9Agzrm-twdS_A 提取码: fh6a

程式可以在winxp下的dos,或dosbox下,或纯dos下运行.
代码约160行(附小量解释):
程序代码:

StepRange    equ 20
X_Range        equ 32
Y_Range        equ 32
XLimit         equ 320 - X_Range
YLimit         equ 200 - Y_Range
DelayTime     equ 1
Unit        equ 3
;--------------------------------------------------------------------
data segment

 starx dw 320/2 - (X_Range/2)

 stary dw 200/2

 StepCount dw 10

 Direction dw 0

 handle    dw 0ffffh

 Flydata db 1024 dup (?)

 FlyFile db 'flybmp.dat',0

 BufferSeg dw 0

 RandomMove label byte
  db 1*Unit,0,1*Unit,1*Unit,0,1*Unit,-1*Unit,1*Unit
  db -1*Unit,0,-1*Unit,-1*Unit,0,-1*Unit,1*Unit,-1*Unit ;8 direction
data ends
;--------------------------------------------------------------------
code segment
assume cs:code,ds:data
start:

 mov ax,data  

 mov ds,ax

 mov bx,offset End_offset + 4096

 add bx,15                   ;add mcb
mov cl,4

 shr bx,cl                   ; / 16
mov ah,4ah                  ;adjust memory
int 21H

 mov bx,1000h                ;64k for data buffer
mov ah,48h

 int 21h

 jc exit

 mov BufferSeg,ax

 mov dx,offset flyFile

 mov ax,3d00h

 int 21h

 jc exit

 mov handle,ax

 mov bx,handle

 mov ah,3fh

 mov cx,1024

 mov dx,offset Flydata

 int 21h                     ; Read one line into the buffer.
jc exit

 cld

 mov ax,0013h

 int 10h

 call Movefly

 mov ax,0003h

 int 10h
exit:

 mov ax,4c00h    ;结束
int 21h
;--------------------------------------------------------------------
Movefly:

 call Random

 mov bx,8    ;0-8 ?
xor dx,dx

 div bx

 shl dx,1    ;byte to word
mov direction,dx

 call Random

 mov di,StepRange  ;0-10 ?
xor dx,dx

 div di

 inc dx

 mov StepCount,dx  ;min = 1
Ms10:

 mov ax,DelayTime

 call Delay

 mov ah,1

 int 16h

 jnz Mx        ;quit
call DrawStar
;
mov bx,direction

 mov al,RandomMove[bx]

 cbw        ;byte to word
add ax,StarX

 cmp ax,XLimit

 ja @f

 mov StarX,ax
@@:

 xor ax,ax

 mov al,RandomMove[bx+1]

 cbw        ;byte to word
add ax,StarY

 cmp ax,YLimit

 ja @f

 mov StarY,ax
@@:  

 dec StepCount

 jnz Ms10

 jmp short Movefly  
Mx:

 ret
;--------------------------------------------------------------------
DrawStar:

 push ds

 mov ax,BufferSeg

 mov es,ax

 mov cx,320*200 /2

 xor ax,ax

 xor di,di

 rep stosw

 mov ax,StarY

 mov bx,320

 mul bx

 add ax,StarX

 mov di,ax

 mov cx,Y_Range

 mov si,offset FlyData
Ds10:

 push di

 push cx

 mov cx,X_Range

 rep movsb

 pop cx

 pop di

 add di,320    ;1 line
loop Ds10

 mov di,0

 mov si,0

 mov ax,BufferSeg

 mov ds,ax

 mov ax,0A000h

 mov es,ax

 mov cx,320*200/2

 rep movsw

 pop ds

 ret
;--------------------------------------------------------------------
Delay:  ;迟延 ax/18秒的子程序
push es

 push dx

 mov dx,40h

 mov es,dx

 mov dx,es:[006ch] ;40:6ch..每1/18累加一次
add dx,ax ;目前累计时数+迟延数=目的迟延数
delay10:

 cmp es:[006ch],dx ;是否到达目的迟延数
jbe delay10 ;还没
delayx:

 pop dx

 pop es

 ret
;--------------------------------------------------------------------
;
dos / 16 bit 取乱数子程序
;
cpu每5ns累加一次,用RDTSC读取,放EDX:EAX
;
因为某些编译器不懂RDTSC, 0fh,31h是机器码植入
Random: ; (Return AX : 0 - 32bit EAX)
db 0fh,31h ;RDTSC
ret
;--------------------------------------------------------------------
End_offset:
code ends
end start


[此贴子已经被作者于2020-3-13 19:58编辑过]

#8
热心网友2020-03-14 08:34
谢谢
#9
nightleon2020-03-19 10:45
好高深
#10
drawee2020-04-14 22:26
#11
热心网友2020-07-19 13:17
这个.BAT文件里写的什么数据?
#12
Valenciax2020-07-20 05:43
回复 11楼 热心网友
啥 .bat ?
#13
热心网友2020-07-20 14:04
.DAT打错了
#14
Valenciax2020-07-20 16:50
回复 13楼 热心网友
flybmp.dat吗? 就是蜻蜓的点阵图
#15
热心网友2020-07-20 19:15
能发下吗,谢谢
#16
Valenciax2020-07-20 19:41
7楼不是已经有百度下载吗?
#17
热心网友2020-07-20 19:56
但我不知道里面的内容,我的意思是让你发里面的内容
#18
Valenciax2020-07-21 06:33
回复 17楼 热心网友
flybmp.dat就是一个点阵图.

在不同绘图模式下,视讯页上每一个字节可以代表不同的颜色值.
比如模式13h是300x200x256, 320x200是屏幕的长和高,256是颜色.
320x200=64000,这64000里,每一个字节是一个颜色,1字节0-ffh=0-255=256种颜色

flybmp.dat内容是一个蜻蜓32x32的点阵图,可以简化的看成这样
0001000
0111110
0001000
0001000
0011100
0001000

1代表某个颜色,0代表无色

然后程式就读取这个dat.直接放到显示页就是了.
这种点阵图可以自己画,甚至不必放在外面,放在data区也可以.

事实上,256色只是16万种颜色中的256种,涉及到3原色RGB红绿蓝的比例
怎样自定16万种颜色中哪256色,还须加上设定色盘的代码.
7楼的代码为了简明就省略了.

所以看起来蜻蜓的配色好像比较淡,不符合蜻蜓该有的鲜艳.
就是因为没有设定色盘,只用系统默认的256色而已.
#19
热心网友2020-07-21 08:15
明白了
#20
Valenciax2020-07-22 21:59
上面提到很久以前我用汇编写的DOS RPG游戏(只写了雏型),也是用320x200的13h模式,写显存的方式基本和小蜻蜓一样,但是调整了色盘,所以看来正常许多.
翻出来勉怀一下.

那时只找到繁体字库,于是用的是繁体字.
只有本站会员才能查看附件,请 登录



[此贴子已经被作者于2020-7-22 22:00编辑过]

#21
热心网友2020-07-23 14:27
真的厉害
1