home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HOT Scene Stuff
/
hotscenestuffzyklop1996.iso
/
diskmags
/
deutsch
/
blckmail
/
bm08
/
asmk3.bmt
< prev
next >
Wrap
Text File
|
1994-09-07
|
12KB
|
239 lines
HEY! ICH BIN WIEDER DA, RETTE SICH WER KANN !!!!
────────────────────────────────────────────────
Nachdem die ersten beiden Teile so eine Art einführenden Beitrag zu
dem Thema liefern sollten, kann man/frau ja mal mit interessanteren
Themen anfangen, wie da wäre z.B. die GRAFIK, der SOUND über den
Soundblaster usw., da gibt's wohl so schnell kein Ende, weil ja
jeder Schöne Sachen programmieren will, das ganze soll schnell
und zügig laufen, nicht flackern etc. etc. ... o.k. die Lösungen
findet ihr zwar nicht hier, aber zumindest einige Ansätze, mit denen
ihr schon auf den richtigen Weg geführt werdet... AMEN.
Also eine kleine Checkliste:
- der Grafikmodus 320*200 - 256 Farben / der Aufbau / => der Punkt
- die Farben und Palettenveränderungen
- das Plasma aus'm letzten Intro
Der Grafikmodus ******************************************************
Der am weitestenverbreitete Grafikmodus für Spiele und Demos ist der
VGA-Standard-Modus $13.. eingestellt wirden der Modus, wie (fast) alle
über den Int $10, also "mov ax,Modusnr/int 10h". => in diesem Fall:
mov ax,13h
int 10h
Hier hat man den Vorteil über 256 von 2^18 Farben gebieten zu können,
aber das war's auch schon fast an Vorteilen, die Auflösung beträgt nur
320*200 (was natürlich den Vorteil hat, daß man ein Bild schnell auf-
gebaut hat). Die Adresse des "Bildschirms" befindet sich an dem Segment
$A000. Die Punkte werden hier, da für jeder Punkt 8 Bit benötigt werden,
jeder in einem eigenen Byte gespeichert, Punkt 1 an $A000:0000, Punkt 2
an $A000:0001 usw. (in Wirklichkeit wird es anders gespeichert, aber so
kann man auf die Pixel zugreifen). Die Reihenfolge ist von links nach
rechts und oben nach unten (ach nee), folglich kann man einfach
berechnen, daß jeder Punkt an der Stelle $A000:x+y*320 liegt, in
Assembler sieht das dann so aus:
; Die Koordinaten sind in den Registern CX/DX, die Farbe in BL
mov di,0a000h ; <- Hier wird das Segment im ES gespeichert, damit
mov es,di ; man dort schreiben kann
mov ax,320 ; <- Man kann nun in AX 320 mit DX multiplizieren,
mul dx ; (DX wird zerstört!! 32-Bit Ergebniss!)
mov di,ax ; <- und in einem Indexregister speichern
add di,cx ; <- dazu kommt der X-Anteil des Punktes
mov [es:di],bl ; <- Nun nur noch die Farbe an den Punkt schreiben
Der Nachteil dieses Modus ist, daß man hier (ohne großen Aufwand zu
betreiben) nur eine Bildschirmseite hat, und folglich nichts ver-
steckt aufbauen kann...dafür müßte man das Chainen der vier Planes auf-
heben, was allerdings ein kleiner Aufwand ist, und das Setzten/Lesen
von Pixeln etwas verkompliziert, aber dazu vielleicht später etwas
mehr...
Die Farben *********************************************************
Klar, es gibt 256 Farben, angefangen wird natürlich mit Farbe 0, die
auch die Hintergrund-(und Rand-)farbe ist, die Standardpalette ist
aber nur in den wenigstens Fällen ausreichend und kann für jeden
beliebigen Zweck manipuliert werden. Das Verändern der Farbregister
kann über zwei verschiedene Wege erreicht werden, einmal durch den
Videointerrupt:
mov ax,1010h ; <- Funktionsnummer: Farbenregister ändern
mov bx,Farbnummer ; <- die Farbe
mov dh,Rotanteil (0-63) ; <- Die Komponenten
mov ch,Grünanteil (0-63)
mov cl,Blauanteil (0-63)
int 10h ; Ausführen des Interrupts
Falls der Aufwand für 256 Farben (oder ein geringerer Teil) zu groß
erscheint kann man das natürlich auch durch eine andere Funktion er-
setzten, nur sollte man die Farbanteile in einer Tabelle gespeichert
haben, jeweils den Rot-, Grün- und Blauanteil mit einem Byte:
mov ax,1012h
mov bx,Nummer der 1. zu ändernden Farbe
mov cx,Anzahl der zu ändernden Farbe
mov es,SEGMENT der Tabelle
mov dx,OFFSET der Tabelle
int 10h
Will man die Werte eines Registers auslesen, so verwendet man jeweils
die Funktionen 1015h für eine Farbe, oder 1017h um einen ganzen Block
auszulesen ... will man nun die Arbeit nicht einem Interrupt überlassen,
so kann man die ganze Sache auch persönlich in die Hand nehmen, indem
man die Ports anspricht:
mov dx,3c8h
mov al,Farbnummer
out dx,al
inc dx
mov al,Rotanteil
out dx,al
mov al,Grünanteil
out dx,al
mov al,Blauanteil ; <- *
out dx,al
Bei manchen Grafikkarten entsteht hierbei ein ziemlicher Schnee auf dem
Bildschirm (z.B. bei meiner), aus welchem Grund auch immer, dann sollte
man den horizontalen Strahlenlauf abfragen und beim Rücklauf den Blau-
wert setzten, die Zeit hierfür reicht aus, da muß man nicht bis zum
vertikalen Strahlenrücklauf warten... Hierfür muß man an der Stelle (*)
einfach noch folgenden Source einsetzten:
mov dx,$03da ; <- Abfragen des H-Sync
@Wait1:
in al,dx
test al,1
jnz @Wait1
@wait2:
in al,dx
test al,1
jz @wait2
mov dx,$03c9 ;<- zurücksetzten des DX-Registers, weiter mit Blau
Tja, bei manchen Karten ist es halt nötig, und bei anderen nicht, schon
ärgerlich wenn es keine reine Standards gibt, z.B. auch die hochauf-
lösenden Modi..tja... nu', falls man auf diese Weise mehrere Farben
verändern will, so muß man leider für sämtliche Farben diese Prozedur
durchlaufen ... alles hat seinen Preis.
Das Plasma aus'm letzten Intro ***************************************
Als ich das Plasma im Intro sah war ich doch 'n bischen unglücklich...
wollte Midnight doch das Wackeln weglassen und dafür nur die Palette
rollen lassen, und es nun genau umgekehrt gemacht hat...aber damit
nun jeder selbst entscheiden kann, was man machen möchte, erkläre ich
diese relativ simple Art ein Plasma zu erzeugen:
1. Man erzeugt eine Tabelle, in der eine Sinuskurve gespeichert ist,
da das Zugreifen auf einen gespeicherten Wert wesentlich schneller
geht, als jedesmal den Wert neu zu berechnen (verständlicherweise).
2. Man erstellt eine nette Palette, die durchgescrollt eine schöne
Farbgebung ergibt...
3. Man läßt nun jeden Punkt des Bildschirms durch einige Sinustrans-
formationen rasseln, malt ihn auf'n Schirm..
4. Man rollt die Palette, bis eine Taste gedrückt wird....
Wahlweise kann man auch eine Laufvariable einfügen, die das bestehende
Muster jeweils ein bischen verändert, in diesem Beispiel ist das
die Variable I, die abder eben entweder weggelassen werden kann, oder
einfach nur das "inc i" weglassen, und da immer nur die selben Punkte
übergemalt werden, wird keine Veränderung sichtbar...
Also, los geht's mit Schritt 1: Hmmm, eine ordentliche Sinuskurve
mit'm Assembler zu erstellen ist doch wohl etwas aufwendig, also
erstelt eine mit Pascal und speichert sie als Textfile ab, so daß
man sie im Assembler includen kann... das ist das beste, was man
in Arbeit/Ergebniss bekommen kann...
Schritt 2 ist Geschmackssache, man könnt es so anfangen, indem pal
ein Feld mit 768 Bytes ist (256*3) und dann mit
mov di,SEG pal
mov es,di
mov di,OFFSET pal
cld
mov ax,0
mov cx,384
stosw
erstmal auf Null setzt, damit man nur noch dort was eintragen muß,
wo man Farbe haben will, also:
mov bl,0
mov di,OFFSET pal ; di als Zeiger auf die Palette
schleife:
mov [di+2],bl ; 0-63 als schwarz -> blau
mov [di+64],bl ; 64-127 als blau -> weiß
mov [di+65],bl
mov [di+66],63
mov [di+128],63 ; 128-191 als weiß -> blau
sub [di+128],bl
mov [di+129],63
sub [di+129],bl
mov [di+130],63
mov [di+192],63 ; 192- als blau -> schwarz
sub [di+192],bl
add di,3
inc bl ; Schleife weiterrasseln
cmp bl,64
jne schleife
In etwa so, oder so ähnlich, natürlich muß man nachher noch die
Palette in der Tabelle ausgeben, aber so o.s.ä. kann man einen
einigermaßen netten Farbenverlauf hinbekommen.
Also nun zum eigentlichen Plasmamuster... zuerst brauchen wir noch
eine Hilfsvariable im Datensegment, da wir nicht genug Register
haben... nenne mer se Y (a star was born)..
cld
mov dx,0a000h ; Ausgabe in'n Screen
mov es,dx
@Start_all:
mov y,199 ; Die Zeile
@y_schl:
mov cx,319 ; schleifenanfang für X-Achse
xor ah,ah ; grafikoffsetanfang
mov al,y
mov bx,320
mul bx
mov di,ax
mov si,OFFSET sin ; si+bx auf richtigen eintrag
@x_schl:
mov al,128 ; nun folgende Sinuswerte addieren
mov bl,i ; sin(2*i+y)
add bl,i
add bl,y
add al,[si+bx]
mov bl,cl ; sin(x+i)
add bl,i
add al,[si+bx]
mov bl,y ; sin(2*y+4)
add bl,4
add bl,y
add al,[si+bx]
xor al,00010000b ; optional "Schlieren" , mal die 1 ausprobieren
add bl,cl ; sin(y+2*x+i)
add bl,cl
add bl,i
add al,[si+bx]
or al,1 ; <- beim Rollen kann man manchmal die 0 nicht rollen
stosb
loop @x_schl ; schleifenende
dec y
jnz @y_schl
; inc i ; <- je nach Geschmack (s.o.)
in al,$60 ; Entweder bis Tastendruck, oder halt nur ein-
cmp al,10000000b ; mal durchlaufen, s.o....
ja @Start_all
Das wichtigste ist entweder das Verändern der Laufvariable, oder
das rollen der Palette, um die Veränderungen zu machen...da braucht
man nur noch die Palette folgende Prozedur durchlaufen zu lassen,
nachdem man einen Zwischen von 3 Byte (r) angelegt hat...
mov ax,SEG pal ; Sicherheitskopie der ersten drei Byte
mov es,ax
mov di,OFFSET pal
mov si,OFFSET r
mov ax,[es:di]
mov [si],ax
mov al,[es:di+2]
mov [si+2],al
mov si,OFFSET pal ; Rollen der Farben um eine Pos. nach unten
add si,3
cld
mov cx,765
rep movsb
mov si,OFFSET r ; Kopieren des Anfang an das Ende
mov cx,3
rep movsb
Na schön, abgesehen davon, daß es in den diversen Teilen so einen oder
mehrere Fehler geben könnte, stimmt der Rest....ok, das war's für
dieses Mal, ich warte auf Vorschläge für'n nächsten Durchgang....
Trader