;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