我目前正在使用dosbox学习tasm中的图形编程。我一直在使用一堆循环来绘制正方形像素块,而且非常难。我想知道是否有一种阅读图像并显示它的方法。我知道如何读取txt文件可能这是一个开始。请帮忙
答案 0 :(得分:1)
您需要编写/使用图像加载器或使用您自己的图像文件格式。 BMP 可能看起来很简单,但有太多像压缩像素格式等,但您仍然可以专注于特定类型的 BMP 并忽略所有其他...
回到 MS-DOS 的时代,我使用256色 PCX 图像和调色板,因为我使用256色视频模式。这里 NASM LINEZ 游戏示例:
请参阅pcx:
子例程。它将加载的 PCX 文件从内存ds:0
解码为es:di
处的原始 VGA 图像。请注意它只支持64 KByte
大小限制!!!
现在要将图像可视化,您必须将es:di
内容复制到 VideoRAM (假设为A000:0000
),例如rep movsd
,或者您可以设置es:di
首先是它(但可能闪烁)。
此 PCX 加载程序不使用图像中的调色板,因此您需要对其进行编码...(更改 VGA 调色板的例程包含在源代码中只需要从 PCX 中提取 RGB 值,我认为它位于文件末尾)点击此处:
如果将PCX转换为32位原始图像。
有关 MS-DOS 游戏编程的详细信息,请参阅PCGPE 1.0
这是另一个使用自己的图片文件格式的游戏示例( TASM ):
它有文本菜单,二进制文件访问,320x200精灵图形,3个人类玩家
[Edit1]新代码
我删除了旧的代码示例,而是使用 TASM 中的调色板查看器创建了可编译且工作的8位 PCX 。它使用 VESA 800x600x256
颜色模式(103h
)。
图片必须适合屏幕,文件大小必须小于64 KB!
我没有添加任何支票或错误消息......它只是加载文件image.pcx
并将其显示在 VESA 上,然后等待按键命中结束退出。这里是 TASM 来源:
<强> PCX.ASM 强>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.386
IDEAL
MODEL TINY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DATASEG
file: db 'image.pcx',0 ;filename to load
buff:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODESEG
STARTUPCODE
scrxs equ 800
scrys equ 600
mov ax,103h ; VESA 800x600x256
call vesamod
mov al,0
call vesapag
; scrxs equ 320
; scrys equ 200
; mov ax,19 ; VGA 320x200x256
; int 10h
lea dx,[file] ; load PCX into DS:buff, CX bytes
call fopen
lea dx,[buff]
mov cx,64000 ; some max value to fit into DS segment
call fread ; CX is PCX real size
call fclose
lea si,[buff] ; decode directly to VRAM
mov ax,0A000h
mov es,ax
mov di,0
call pcx
mainl0:
mov ax,256 ; test keyboard
int 16h
jz mainl0
sub ax,ax ; clear key buffer
int 16h
mov ax,3 ;|VGA 80x25 text
int 16
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
vesamod:pusha ;set VESA videomode ax
mov bx,ax
mov ax,4f02h
int 16
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
vesapag:pusha ;al=page switch vesa video page window A
mov [cs:scrpag],al
mov dl,al
sub dh,dh
sub bx,bx
mov ax,4f05h ; window A
int 16
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .386P
scrpag db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .386P
hand dw 0 ;### handler...
ferr db 0 ;### DOS error code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fopen: pusha ;DS:DX = file name, [hand] <= file handle
mov ax,3D02h
int 21h
mov bl,0
jnc fopen0
mov bl,al
sub ax,ax
fopen0: mov [cs:hand],ax
mov [cs:ferr],bl
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fclose: pusha ;[hand] = file handle
mov bx,[cs:hand]
mov ah,3eh
int 21h
mov bl,0
jnc fclose0
mov bl,al
sub ax,ax
fclose0:mov [cs:ferr],bl
mov [cs:hand],ax
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fread: pusha ;DS:DX = adr, CX = lenght, [hand] = hand, CX => read
mov bx,[cs:hand]
mov ah,3Fh
int 21h
mov bl,0
jnc fread0
mov bl,al
sub ax,ax
fread0: mov [cs:ferr],bl
mov [cs:freadsz],ax
popa
mov cx,[cs:freadsz]
ret
freadsz dw 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pcx: pusha ;decode pcx at ds:si to es:di cx = PCX size
push ds
push es
push ecx
push edx
push si ;set palette
add si,cx
sub si,768
sub ax,ax
pall0: mov dx,3C8h
mov al,ah
out dx,al
inc dx
lodsb
shr al,2
out dx,al
lodsb
shr al,2
out dx,al
lodsb
shr al,2
out dx,al
inc ah
jnz pall0
pop si
mov ax,[ds:si+8] ;get xs
sub ax,[ds:si+4]
inc ax
mov [cs:pcxxs],ax
mov [cs:pcxx],ax
mov ax,[ds:si+10] ;get ys
sub ax,[ds:si+6]
inc ax
mov [cs:pcxys],ax
mul [cs:pcxxs]
push dx
push ax
pop edx
add si,128 ;src start after pcx header
sub ecx,ecx ;RLE decoder of PCX
pcxl0: lodsb
mov cx,1
cmp al,192
jb pcxr0
mov cl,al
and cl,63
lodsb
pcxr0: mov bx,cx
pcxl1: call point
dec [cs:pcxx] ;correct next screen line position if end of PCX line
jnz pcxr1
mov ax,[cs:pcxxs]
mov [cs:pcxx],ax
neg ax
add ax,scrxs
add di,ax
jnc pcxr1
; page swith
mov al,[cs:scrpag]
inc al
call vesapag
pcxr1: loop pcxl1
mov cx,bx
sub edx,ecx
jz pcxesc
jnc pcxl0
pcxesc: pop edx
pop ecx
pop es
pop ds
popa
ret
pcxxs dw 0 ;PCX resolution
pcxys dw 0
pcxx dw 0 ;actual X coordinate
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
point: mov [es:di],al ;point ;estosb
inc di
jnz pntesc
; page swith
mov al,[cs:scrpag]
inc al
call vesapag
pntesc: ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
所以拍摄任何图像到800x600
将其转换为带有调色板的256色PCX并将其重命名为image.pcx
。然后将其放入*.com
文件并运行。我用Volcov commander扩展脚本vc.ext
编译它,如下所示:
asm:@c:\language\compil\tasm\tasm !.! /ic:\language\source\tasm\inc
@c:\language\compil\tasm\tlink !.obj /t /x
@del !.obj
所以每次我在任何asm文件上按Enter键都会编译。只需更改路径,如果您没有定位*.com
个文件,请相应更改/t
开关。这里从我的 DOSBox 预览: