Paint


;PAINT


;PAINT
.286


;--------------------------------------------------------------------------------------------------------------------------------
; Macros
;--------------------------------------------------------------------------------------------------------------------------------


GetGM macro ; Guarda o mode gr·fica actual (Get Graphic Mode)
mov ah, 0fh ; verifica o modo gr·fico actual
int 10h ; invoca a interrupÁ„o 10h da BIOS
push ax ; guarda o modo gr·fico actual (ah - n de colunas, al - modo gr·fico)
endm

RstGM macro ; Restaura o modo gr·fico guardade (Restore Graphic Mode)
pop ax ; volta ao modo gr·fico anterior
mov ah, 00h ; prepara para definir o modo gr·fico
int 10h ; invoca a interrupÁ„o 10h da BIOS
endm


SetGM macro ; inicia modo gr·fico
pusha
mov ah, 00h ; selecciona o modo gr·fico
mov al, 13h ; configura o modo 19 (ou 13h) 320x200 com 256 cores
int 10h ; invoca a interrupÁ„o do modo gr·fico
mov ax, 0a000h ; indica o edereÁo de memÛria onde comeÁa a memÛria gr·fica
mov es, ax ; coloca o endereÁo em "es"
cld ; activa a auto incrementaÁ„o de "SI" e "DI" apÛs uma leitura ou escrita na memÛria
popa
endm


StartMouse macro
pusha
mov ax, 00h ; inicia o rato
int 33h ; invoca a interrupÁ„o do rato
popa
endm


ShowMouse macro
pusha
mov ax, 01h ; mostra o cursor do rato
int 33h ; invoca a interrupÁ„o do rato
popa
endm


HideMouse macro
pusha
mov ax, 02h ; esconde o ponteiro do rato
int 33h ; invoca a interrupÁ„o do rato
popa
endm


createfil macro
mov ah, 3ch
mov cx, 00h
lea dx, instring
add dx, 2
int 21h
endm


openreadfil macro
mov al, 00h
mov ah, 3dh
lea dx, instring
add dx, 2
int 21h
mov fhand, ax
endm


openwritefil macro
mov al, 01h
mov ah, 3dh
lea dx, instring
add dx, 2
int 21h
mov fhand, ax
endm


indexnum macro
mov al, 02
mov ah, 42h
mov bx, fhand
mov cx, 00h
mov dx, 00h
int 21h
endm


writefil macro
mov ah, 40h
mov bx, fhand
int 21h
endm


readfil macro
pusha
mov ah, 3fh
mov bx, fhand
mov cx, 1
lea dx, byteread
int 21h
popa
endm


readimgfil macro
pusha
mov ah, 3fh
mov bx, fhand
mov cx, 64000
lea dx, storeBuff
int 21h
popa
endm


closefil macro
mov ah, 3eh
mov bx, fhand
int 21h
endm


;--------------------------------------------------------------------------------------------------------------------------------
;Stack Segment
;--------------------------------------------------------------------------------------------------------------------------------


Stack Segment Para Stack
db 64 dup('Stack ')
Stack Ends


;--------------------------------------------------------------------------------------------------------------------------------
;Data Segment
;--------------------------------------------------------------------------------------------------------------------------------


Data Segment Para 'Data'


posX dw ? ; coordenada x da posiÁ„o actual do ponteiro
posY dw ? ; coordenada y da posiÁ„o actual do ponteiro

selXbeg dw ? ; coordenada x do canto superior esquerdo da selecÁ„o
selYbeg dw ? ; coordenada y do canto superior esquerdo da selecÁ„o

selXend dw ? ; coordenada x do canto inferior direito da selecÁ„o
selYend dw ? ; coordenada y do canto inferior direito da selecÁ„o

horLeng dw ? ; selXend - selXbeg
horLengOld dw ? ; guarda o valor anterior de horLeng quando copia
verLeng dw ? ; selYend - selYbeg
verLengOld dw ? ; guarda o valor anterior de verLeng quando copia

horStop dw ? ; posX + horLeng (ponto de paragem do Paste)
verStop dw ? ; posY + verLeng (ponto de paragem do Paste)

storeBuff db 64000 DUP (' ')

currColor db 0fh ; guarda o valor da cor actual, iniciado a 0fh (branco)

fhand dw ?

endlin db 0ah,0dh,'$'
prompt db 'Localizacao do ficheiro (20 BYTES MAX): ','$'
instring db 21,21 dup (' '),'$$',0

header db 'P5',10
db 'Ficheiro Gerado Por Pinta V1.0 Autores: Diogo Silva e LuÌs Mendes',10
db '300 200',10
db '255',10

imgsizevert dw ?
imgsizehor dw ?

byteread db ?

Data Ends


;--------------------------------------------------------------------------------------------------------------------------------
;Code Segment
;--------------------------------------------------------------------------------------------------------------------------------


Code Segment Para 'Code'


;================================================


; Main
Main proc far
assume cs:Code, ds:Data, es:Data, ss:Stack
push ds ; guarda o endereÁo de ds na pilha
sub ax, ax ; coloca o ax a 0
push ax ; coloca o valor de ax na pilha
mov ax, data ; copia o endereÁo de data segment para ax
mov ds, ax ; copia o endereÁo de ax para o registo ds

GetGM ; guarda o modo gr·fico actual
SetGM ; inicia o modo gr·fico 320x200 a 256 cores


StartMouse ; chama a rotina para iniciar o rato
call DrawPallet ; desenha a palete no ecran
call ShowCurrCol ; desenha uma area que mostra a cor escolhida

ifNotKeyPressed:
call CheckMouse ; chama a rotina que verifica o estado do rato
cmp bl, 01h ; verifica se o bot„o esquerdo do rato foi pressionado (0001 em bin·rio)
jb dontDraw ; se n„o foi pressionado n„o desenha o pixel
cmp bl, 02h ; verifica se o bot„o direito do rato foi pressionado (0010 em bin·rio)
jne contDraw ; Desenha o px
call SelectArea ; chama a rotina que selecciona uma area a copiar
jmp dontDraw ; n„o desenha
contDraw:
call Draw ; chama a rotina que desenha o pixel
dontDraw:
mov ah, 01h ; verifica se alguma tecla foi pressionada
int 16h ; chama a interrupÁ„o de chamada ao sistema operativo
jz ifNotKeyPressed
mov ah, 00h ; uma tecla foi pressionada
int 16h ; È necess·rio captura-la para n„o aparecer na consola
cmp al, 1bh ; verifica se a tecla pressionada È "Esc" (ASCII - 1Bh).
je theEnd ; se n„o È continua o programa normalmente
cmp al, 'c'
jne nCopyArea
call CopyArea
nCopyArea:
cmp al, 'p'
jne Clear
call PasteArea
Clear:
cmp al, 'd'
jne Ofile
call Refresh
Ofile:
cmp al,'o'
jne Sfile
call img
call fich
closefil
Sfile:
cmp al, 's'
jne ifNotKeyPressed
call img2

;call fich
createfil
openwritefil
indexnum
call wdata
closefil
call Refresh
jmp ifNotKeyPressed
theEnd:
RstGM ; Restaura o modo gr·fico guardado no inicio do programa

ret ; sai do programa
Main endp


;================================================
; converte de ascii para bin
convert proc
push ax
mov cx, 10
mov ax, bx
mul cx
mov bx, ax
pop ax
mov ah, 0h
sub al, 30h
add bx, ax
ret
convert endp


;================================================
; pede o nome do ficheiro ao utilizador e abre-o
img proc
xor bx, bx
mov ah, 0h
mov al, 03h
int 10h
mov ah, 09
lea dx, prompt
int 21h

mov ah, 0ah
lea dx, instring
int 21h

mov ah, 09
lea dx, endlin
int 21h

mov al, instring + 1
add al, 2
cbw ; converte al, em word ax al -> ax
mov bx, ax
mov instring[bx], ' '

mov ah, 09 ;
lea dx, instring ;
add dx, 2 ; avanÁa dois bytes (bytesmax, byteslidos)
int 21h

mov ah, 09
lea dx, endlin
int 21h

ret
img endp


img2 proc
mov selXbeg,20
mov selYbeg,0
mov selXend,320
mov selYend,200
call CopyArea
xor bx, bx
mov ah, 0h
mov al, 03h
int 10h
mov ah, 09
lea dx, prompt
int 21h

mov ah, 0ah
lea dx, instring
int 21h

mov ah, 09
lea dx, endlin
int 21h

mov al, instring + 1
add al, 2
cbw ; converte al, em word ax al -> ax
mov bx, ax
mov instring[bx], ' '

mov ah, 09 ;
lea dx, instring ;
add dx, 2 ; avanÁa dois bytes (bytesmax, byteslidos)
int 21h

mov ah, 09
lea dx, endlin
int 21h

ret
img2 endp


fich proc
call Refresh
openreadfil
jc DontExist
mov fhand, ax
call rdata
DontExist:
ret
fich endp


rdata proc
mov cx,2
lf:
readfil
mov al, byteread
cmp al, 0ah
jne lf
loop lf
xor bx, bx
outro:
readfil
mov al, byteread
cmp al, 20h ; 20h = espaÁo
je guarda1
cmp al, 0ah ; 0ah = LF
je guarda2
call convert
jmp outro
guarda1:
mov imgsizehor, bx
xor bx, bx
jmp outro
guarda2:
mov imgsizevert, bx

lf1:
readfil
mov al, byteread
cmp al, 0ah
jne lf1

readimgfil

mov ax, imgsizevert
mov verLengOld, ax

mov ax, imgsizehor
mov horLengOld, ax

mov selXbeg, 20
mov posX,20
mov posY,0
call PasteArea

ret
rdata endp


wdata proc

mov cx, 81
lea dx, header
writefil

mov cx,60000
lea dx,storeBuff
writefil
ret
wdata endp


;================================================
; verifica estado do rato
CheckMouse proc
mov ax, 03h ; funÁ„o que retorna informaÁ„o do rato
int 33h ; invoca a interrupÁ„o do rato
mov posX, cx ; guarda a posiÁ„o horizontal do rato
shr posX, 1 ; È necess·rio fazer uma divis„o por dois pois a tela virtual do rato tem 640 pontos horizontais e o ecr„ tem 320
mov posY, dx ; guarda a posiÁ„o vertical do rato
cmp bl, 00h ; verifica se est· algum bot„o pressionado
jne return ; se estiver n„o coloca o cursor visivel
ShowMouse ; mostra o cursor do rato
return:
ret
CheckMouse endp


;================================================
; pinta no ecran
Draw proc
mov cx, posX ; selecciona a coluna
cmp cx, 20 ; verifica se o rato se encontra ‡ esquerda do pixel 20 (palete)
jae PutPixel ; caso se encontre ‡ direita desenha
call ChooseColor ; caso se encontre ‡ esquerda chama a rotina que escolhe a cor da palete
jmp nPutPixel
PutPixel:
HideMouse
mov si, posY
mov ax, 320
mul si
mov di, ax
add di, cx
mov al, currColor
stosb
nPutPixel:
ret
Draw endp


;================================================
; desenha no lado esquerdo do ecran uma palete de cores
DrawPalletLine proc
pusha
mov ah, 12
xor bx, bx
xor cx, cx
PutDot1:
int 10h
inc cx
cmp cx, 5
jb PutDot1
cmp al, 10h
jb PutDot2
add al, 60
PutDot2:
int 10h
inc cx
cmp cx, 10
jb PutDot2
cmp al, 10h
jb PutDot3
add al, 60
PutDot3:
int 10h
inc cx
cmp cx, 15
jb PutDot3
cmp al, 10h
jb PutDot4
add al, 60
PutDot4:
int 10h
inc cx
cmp cx, 20
jb PutDot4
popa
ret
DrawPalletLine endp
;================================================
DrawPallet proc
pusha
xor ax, ax
xor dx, dx
mov cx, 76
PutLines:
call DrawPalletLine
inc dx
call DrawPalletLine
inc dx
inc ax
loop PutLines
popa
ret
DrawPallet endp


;================================================
; Mostra um quadrado com a cor currente
ShowCurrCol proc
pusha
mov dx, 152 ; linha de comeÁo

NextLine:
mov si, dx ; linha (dx)
mov ax, 320
push dx
mul si
pop dx
mov di, ax
mov al, currColor
mov cx, 20
rep stosb
inc dx
cmp dx, 200 ; compara com a linha final
jb NextLine

popa
ret
ShowCurrCol endp


;================================================
; Selecciona a cor da palete
ChooseColor proc
pusha
HideMouse
mov si, posY
mov ax, 320
mul si
mov di, ax
add di, posX
mov al, es:[di]
mov currColor, al
call ShowCurrCol
popa
ret
ChooseColor endp


;================================================
; Selecciona uma zona do ecran
SelectArea proc
mov ax, posX
mov selXbeg, ax
mov ax, posY
mov selYbeg, ax
select:
mov ax, 03h
int 33h
mov selXend, cx
shr selXend,1
mov selYend, dx
cmp bx, 02h
je select

CompHor:
mov ax, selXbeg
mov bx, selXend
cmp ax, bx
jb CompVer
mov selXbeg, bx
mov selXend, ax

CompVer:
mov ax, selYbeg
mov bx, selYend
cmp ax, bx
jb CalcDim
mov selYbeg, bx
mov selYend, ax

CalcDim:
mov ax, selXend
sub ax, selXbeg
mov horLeng, ax
mov ax, selYend
sub ax, selYbeg
mov verLeng, ax

ret
SelectArea endp


;================================================
; copia a ultima area seleccionada
CopyArea proc

mov ax, horLeng
mov horLengOld, ax

mov ax, verLeng
mov verLengOld, ax

HideMouse ; esconde o ponteiro do rato

xor bx, bx
mov dx, selYbeg
rep1:
mov cx, selXbeg
rep2:
xor ax, ax
push bx
mov ah, 13
mov bh, 00h
int 10h
pop bx
mov storeBuff[bx], al
inc bx
inc cx
cmp cx, selXend
jb rep2
inc dx
cmp dx, selYend
jb rep1


ShowMouse ; mostra o ponteiro do rato
ret
CopyArea endp


;================================================
; cola na posiÁ„o actual a area guardada
PasteArea proc
mov cx, posX ; selecciona a coluna para comparar
cmp cx, 20 ; verifica se o rato se encontra ‡ esquerda do pixel 20 (palete)
jb DontPaste ; caso se encontre ‡ esquerda n„o cola

mov cx, selXbeg ; selecciona a coluna de inicio da selecÁ„o
cmp cx, 20 ; verifica se a selecÁ„o n„o foi feita ‡ esquerda do pixel 20, ou seja, impede a copia da palete
jb DontPaste ; caso se encontre ‡ esquerda n„o cola

HideMouse ; esconde o ponteiro do rato

xor bx, bx

mov ax, posY
add ax, verLengOld
mov verStop, ax


mov ax, posX
add ax, horLengOld
mov horStop, ax


mov dx, posY
rep3:
mov cx, posX
rep4:
mov al, storeBuff[bx]
cmp al, 00h
je DontPutDot
cmp cx, 320
jae DontPutDot
cmp dx, 200
jae DontPutDot
push bx
mov ah, 12
mov bh, 00h
int 10h
pop bx
DontPutDot:
inc bx
inc cx
cmp cx, horStop
jb rep4
inc dx
cmp dx, verStop
jb rep3


ShowMouse ; mostra o ponteiro do rato
DontPaste:
ret
PasteArea endp


;================================================
; cola na posiÁ„o actual a area guardada
Refresh proc
pusha
SetGM
call DrawPallet ; desenha a palete no ecran
call ShowCurrCol
popa
ret
Refresh endp
;================================================


Code Ends
;================================================


End
;--------------------------------------------------------------------------------------------------------------------------------

0 comentários:

Enviar um comentário