В настоящее время я изучаю графическое программирование в tasm, используя dosbox. Я использовал кучу циклов для рисования квадратных блоков пикселей, и это действительно сложно. Я хочу знать, есть ли способ прочитать изображение и отобразить его. Я знаю, как читать текстовый файл, может быть, это начало. Пожалуйста, помогите
Как прочитать файл изображения и отобразить на экране в Windows tasm dosbox
Ответы (1)
Вам нужно написать/использовать загрузчик изображений или использовать свой собственный формат файла изображения. BMP может показаться простым, но в нем слишком много всего, например форматы пикселей сжатия и т. д., но вы все равно можете сосредоточиться на определенном типе BMP и игнорировать все остальные...
Еще во времена MS-DOS я использовал 256-цветные изображения PCX с палитрой, поскольку я использовал 256-цветные видеорежимы. Вот пример игры NASM LINEZ:
см. подпрограмму pcx:
. Он декодирует загруженный файл PCX из памяти ds:0
в необработанное изображение VGA в es:di
. Остерегайтесь, он поддерживает только ограничение размера 64 KByte
!!! Теперь, чтобы визуализировать изображение, вам нужно будет скопировать es:di
содержимое в VideoRAM (при условии, что A000:0000
), например, с rep movsd
, или вы можете установить для него es:di
в первую очередь (но это может мерцать).
Однако этот загрузчик PCX не использует палитру из изображения, поэтому вам нужно ее закодировать... (процедуры для изменения палитры VGA включены в исходный код, который вам просто нужно извлеките значения RGB из PCX, я думаю, это было в конце файла) Посмотрите здесь:
если конвертирует PCX в 32-битный необработанный образ.
Для получения дополнительной информации о программировании игр MS-DOS см. PCGPE 1.0
Вот еще один пример игры (TASM), в котором используется собственный формат файла изображения:
Он имеет текстовые меню, доступ к двоичным файлам, спрайтовую графику 320x200, 3 человека-игрока.
[Edit1] Новый код
Я удалил старый пример кода и вместо этого создал компилируемый и работающий 8-битный PCX со средством просмотра цветовой палитры в TASM. Он использует режим VESA 800x600x256
цветов (103h
).
Изображение должно умещаться на экране, а размер файла не должен превышать 64 КБ!!!
Я не добавлял никаких проверок или сообщений об ошибках ... Он просто загружает файл 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 vc.ext
следующим образом:
asm:@c:\language\compil\tasm\tasm !.! /ic:\language\source\tasm\inc
@c:\language\compil\tasm\tlink !.obj /t /x
@del !.obj
поэтому каждый раз, когда я нажимаю Enter в любом файле asm, он компилируется. Просто измените пути, и если вы не нацелены на файлы *.com
, измените переключатель /t
соответствующим образом. Вот предварительный просмотр из моего DOSBox:
pcx:
это декодер pcx для необработанного 256-цветного изображения без палитры. Таким образом, вам нужно просто скопировать его источник в свой проект и вызвать его с установленными регистрами ... ему нужен только файл, загруженный в память, что вы можете сделать, как вы упомянули, вы можете открыть текстовые файлы и в качестве места назначения выбрать некоторую память или использовать VRAM напрямую . Он написан для видеорежима 320x200x256, поэтому начните с него, и при работе вы можете перекодировать до 800x600 или любого другого.
- person Spektre; 21.08.2017
800x600x256-> 7x64KByte
. Если вы находитесь в защищенном режиме, вы можете получить доступ ко всей VRAM, если отобразите ее как LFB в пространство памяти процессора, но это намного выше моих знаний (я использовал только реальный режим).
- person Spektre; 22.08.2017
include 'filename'
... используются расширения *.asm, *.inc; *.lib
, все они находятся в asm
.
- person Spektre; 22.08.2017
include
просто копирует файл в то место, где находится include
(как в C++), поэтому вам нужно быть будьте осторожны с использованием сегментов DATA и CODE во включаемых файлах... Кстати, я пытался скомпилировать декодер pcx под TASM, но он не работает из-за несовместимости компилятора (он был написан в NASM) Я, должно быть, забыл изменить что-то, чего TASM не делает вроде... ааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааээээээааааааааааааааа, теперь я ненавижу TASM, теперь я вспомнил, почему я перешёл на NASM….
- person Spektre; 22.08.2017
bmp
достаточно просто читать и декодировать, хотя в реальном режиме с сегментами 64k это будет полная PITA для работы в таком высоком разрешении. На самом деле я даже не могу вспомнить, как устроена эта схема памяти в режиме SVGA и что такое банкинг, если каждый 4-й пиксель (не влезает), или каждый бит на 8 плоскостях, или просто весь экран делится на 5+ части. (Я использовал компилятор Watcom C для инициализации всего в защищенном режиме, загрузки файлов, их декодирования и т. д. (все на C/C++) и расширение VBE2.0 для линейного отображения VRAM в защищенном режиме, затем я сделал забавные вещи в 32b asm. , так что все было просто) - person Ped7g   schedule 20.08.2017