如何在 windows tasm dosbox 中读取图像文件并在屏幕上显示 [英] How to read image file and display on screen in windows tasm dosbox

查看:23
本文介绍了如何在 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 memory ds:0 to raw VGA image at es:di. Beware it does support just 64 KByte size limit !!! Now to visualize the image you would have to copy es:di content into VideoRAM (assuming A000:0000) for example with rep movsd or you can set es: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 to image.pcx. Then place it to your *.com file and run. I compiled it with Volcov commander extension script vc.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆