如何在 windows tasm dosbox 中读取图像文件并在屏幕上显示 [英] How to read image file and display on screen in windows tasm dosbox
问题描述
我目前正在使用 dosbox 在 tasm 中学习图形编程.我一直在使用一堆循环来绘制方形像素块,这真的很难.我想知道是否有办法读取图像并显示它.我知道如何阅读 txt 文件,也许这是一个开始.请帮忙
您需要编写/使用图像加载器或使用您自己的图像文件格式.BMP 可能看起来很简单,但其中包含了太多像压缩像素格式等内容,但您仍然可以专注于特定类型的 BMP 而忽略所有其他类型...>
回到 MS-DOS 时代,我使用带有调色板的 256 色 PCX 图像,因为我使用了 256 色视频模式.这里NASM LINEZ游戏示例:
Im currently learning graphical programming in tasm using dosbox. Ive been using a bunch of loops to draw square blocks of pixels and its really hard. I want to know if theres a way to read an image and display it. I know how to read a txt file maybe this is a start. Pls help
解决方案You need to write/use image loader or use your own image file format. BMP may look simple but has too much in it like compression pixel formats etc but you still can focus on a specific type of BMP and ignore all the others...
Back in the days of MS-DOS I was using 256 color PCX images with palette as I used 256 color video modes. Here NASM LINEZ game example:
see the
pcx:
subroutine. It decodes loaded PCX file from memoryds:0
to raw VGA image ates:di
. Beware it does support just64 KByte
size limit !!! Now to visualize the image you would have to copyes:di
content into VideoRAM (assumingA000:0000
) for example withrep movsd
or you can setes:di
to it in the first place (but that could flicker).This PCX loader however does not use palette from the image so you need to encode it ... (the routines to change VGA palette are included in the source you just need to extract the RGB values from PCX I think it was at the end of file) Look here:
if converts PCX to 32bit raw image.
For more info about MS-DOS game programing see PCGPE 1.0
Here another game example (TASM) which uses own image file-format:
It has text menues, binary file access, 320x200 sprite graphics, 3 human players
[Edit1] New code
I removed the old code example and instead I created compilable and working 8bit PCX with color palette viewer in TASM. It uses VESA
800x600x256
colors mode (103h
).The image must fit into screen and its file size must be less than 64 KByte !!!
I did not add any checks or error messages ... It simply loads file
image.pcx
and displays it on VESA then wait on key hit end exit. Here the TASM source: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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
So take any image up to
800x600
convert it to 256 color PCX with palette and rename it toimage.pcx
. Then place it to your*.com
file and run. I compiled it with Volcov commander extension scriptvc.ext
like this:asm:@c:languagecompil asm asm !.! /ic:languagesource asminc @c:languagecompil asm link !.obj /t /x @del !.obj
so each time I hit the enter on any asm file it will compile. Just change the paths and if you are not targeting
*.com
files then change the/t
switch accordingly. Here preview from my DOSBox:这篇关于如何在 windows tasm dosbox 中读取图像文件并在屏幕上显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!