home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HOT Scene Stuff
/
hotscenestuffzyklop1996.iso
/
diskmags
/
deutsch
/
microcod
/
stod1
/
text
/
text013.txt
< prev
next >
Wrap
Text File
|
1994-11-11
|
7KB
|
210 lines
PCX-Bilder in Assembler
-----------------------
Nachdem Ihr sicherlich schon die Theorieabhandlung des PCX-For-
mats gelesen habt, gibt's jetzt etwas Handfestes in Assembler.
Das folgende Programm liest ein 320x200x256-PCX-Bild ein und
bringt es auf die (dann bunte) Mattscheibe. Ich werde mich dabei
wieder an die im 'Theorie-Text' beschriebene Struktur halten.
O.K, ersteinmal das Listing, danach ein paar Anmerkungen:
SHOWPCX320x200x256 PROC
lea dx,DateiName
mov ax,3d00h
int 21h ; Datei öffnen
mov Handle,ax ; FileHandle nach Handle
mov ax,3F00h
mov bx,Handle
mov cx,128
lea dx,Header
int 21h ; Header auslesen
mov Video_Offset,0
mov repeatCount,0
Schleife:
mov ax,3F00h
mov bx,Handle
mov cx,Buff_Size
lea dx,DatenPuffer
int 21h ; 50000b aus PCX-File lesen
jc Ende ; Wenn Fehler aufgetreten -> Ende
cmp ax,0
je MakePalette ;0 Byte gelesen -> Ende
mov BytesRead,ax
call Decode ;Gelesene Bytes decodieren
jmp Schleife
MakePalette:
mov ah,42h
mov al,02h
mov bx,Handle
mov cx,0
mov dx,0
int 21h ;Laenge der Datei bestimmen
sub ax,768 ;DWord (DX:AX) um 768 erniedrigen
jnc nextpal
sub dx,1
nextpal:
mov cx,dx
mov dx,ax
mov ah,42h
mov al,00h
mov bx,Handle
int 21h ;FilePointer 768b vor Ende setzen
mov ah,3Fh
mov bx,Handle
mov cx,768
lea dx,Palette
int 21h ; 768b aus File lesen (in Palette)
lea bx,Palette
mov cx,768
decrease:
mov ah,[bx]
shr ah,2
mov [bx],ah
inc bx
loop decrease ;Alle Farbeinträge durch 4 teilen
mov ax,1012h
mov bx,0
mov cx,256
mov dx,Seg Palette
mov es,dx
lea dx,Palette
int 10h ;256 Farben setzen
DateiSchliessen:
mov ah,3Eh
mov bx,Handle
int 21h ; Datei schließen
ENDE:
ret
ShowPCX320x200x256 ENDP
Decode Proc
mov ax, Page_Addr ; Video-Segment nach AX
mov es, ax ; Video-Segment nach ES
mov di, Video_Offset ; Video_Offset nach DI
xor cx, cx ; CX auf null
mov cl, RepeatCount ; Anzahl der Wiederholungen nach CL
mov bx, BytesRead ; Anzahl der gelesenen Bytes nach BX
lea si, DatenPuffer ; Offset von DatenPuffer nach SI
add bx, si ; Offset-Ende vom Puffer in BX
cld ; Lösche DF - INC DI (stosb/lodsb)
checkbyte:
cmp si, bx ; Noch Daten da?
je exit ; Wenn nicht : EXIT
lodsb ; Lade nächstes Byte nach AL
cmp cl, 0 ; Wiederholungsschleife ?
jne WriteByte ; Wenn ja : WriteByte
cmp al, 11000000b ; Sonst prüfe BIT 7+6 (> 192)
jb VorWriteByte ; Nicht gesetzt -> VorWriteByte
and al, 00111111b ; BIT 0-5 : Wiederholungszähler
mov cl, al ; Wiederholungsanzahl nach CL
jmp checkbyte ; Prüfe nächste Data
VorWriteByte:
mov cl,1
WriteByte:
stosb ; AL in VideoSpeicher, INC DI
cmp di,64000
je Exit ; Wenn 64000 Punkte gesetzt wurden,
; nächstes Fenster einblenden
loop writebyte
jmp checkbyte ; Prüfe nächste Data
exit:
mov Video_Offset, di
mov repeatcount, cl
ret ;Werte zwischenspeichern und zurück
Decode Endp
Das Listing beinhaltet nur die Prozedur zum darstellen des PCX-
Bildes. Der VideoModus 13h (320x200x256) muß gesetzt sein, und
folgendes muß im Hauptprogramm deklariert sein:
Page_Addr equ 0A000h
Buff_Size equ 50000
.DATA
Handle dw (?) ; Filehandle zum Zugriff auf Datei
Header db 128 dup (?) ; Buffer für Header
RepeatCount db (?) ; Wiederholungszaehler
BytesRead dw (?) ; Länge der gelesenen Daten in Byte
Video_Offset dw (?) ; Offset-Addy vom ViedeoRam
DatenPuffer db Buff_Size dup (?) ; Tab für gelesene Bytes
Palette db 768 dup (?) ; Nimmt Palette auf
DateiName db 'test.pcx',0 ; Beliebiger Dateiname
Der angegebene Dateiname sollte wirklich existieren und auch
ein PCX-Bild sein, sonst könnte es zu Problemen kommen. Der
QuellCode ist zwar einigermaßen dokumentiert, läßt aber bestimmt
noch einige Fragen offen. Wenn Ihr genau hinschaut, seht Ihr
aber, daß ich das im Theorieteil beschriebene Schema zum anzei-
gen eines Bildes tatsächlich benutzt habe.
Nachdem die Datei geöffnet und der Header ausgelesen wurde, be-
ginnt die Ausgabe des Bildes (Marke: Schleife). Es werden nach
Möglichkeit 50000 Byte ausgelesen. Die reale Anzahl der gele-
senen Bytes steht im AX-Register. Sollte hier eine Null zu finden
sein, so wurden alle Daten ausgelesen. Danach wird dann die Pa-
lette gesetzt und die Prozedur verlassen. Sollten Daten gelesen
worden sein, so wird die Prozedur 'Decode' angesprungen.
Hier geht's nun (nach der Initialisierung einiger Werte) in
'CheckByte' richtig los. Es wird ein Byte ausgelesen und über-
prüft, ob die obersten beiden Bits gesetzt sind (192...).
Ist das der Fall, so werden diese beiden Bits ausgeblendet
(Byte AND 00111111b). Der verbleibende Wert repräsentiert den
Index, der in CX (dem Wiederholungszähler) gespeichert wird.
Das nächste Byte wird ausgelesen. Da CX > 0 ist, wird WriteByte
angesprungen, wo dieses neue Byte nun in den Videospeicher ge-
schrieben wird (mit STOSB). Dabei wird auch DI erhöht, der
gleichzeitig als 'Pixelzähler' eingesetzt werden kann. Wurden
64000 Pixel gesetzt (320x200), so steht das Bild vollständig
auf dem Bildschirm, und die Palette kann gesetzt werden. Wenn
nicht, wird, nachdem die Pixel gesetzt wurden, wieder von
vorne begonnen.
Sollte bei einem ausgelesenem Byte nicht die obersten beiden Bits
gesetzt sein, so wird das Byte nur einmal in den Speicher ge-
schrieben (VorWriteByte: CX (=Index) auf 1).
Tja, wahrscheinlich ist immer noch nicht alles geklärt, aber
das Grundprinzip dürfte wohl verstanden sein.
Alle die, die noch kein Vorwissen über den 320x200x256-Grafikmo-
dus haben, sollten sich das nächste STOD antun, da dort auch
darüber etwas zufinden sein wird.
Da ich mich noch nicht besonders gut mit den Schlüsselwörtern
Public und Extern etc. auskenne, weiß ich auch nicht, wie ich
obiges als externe Linkdatei angeben kann. Daher diese etwas
aufwendige Methode mit der Deklaration der benutzten Variablen
im Hauptprogramm und nicht in der Prozedur selber. Sollte es
jemand besser wissen, kann er ja mal schreiben...
Tja, das war's dann auch schon mit diesem Artikel. Wenn noch
Fragen offen stehen sollten: immer her damit!
Das Listing befindet sich natürlich auch in dem QuellCode-Pfad
'SOURCES'.
Kemil