Sprites definieren
-
hallo,
bin grad am überlegen, wie ich in assembler sprites anlegen kann ...
d.h. in der sprache c mit SDL zum beispiel hab ich immer bitmaps genommen und
diese bitmaps dann in mein programm eingeladen und als "surface" abgelegt...aber wie geht das in assembler wenn man jetz gar keine externe bitmap-dateien
verwenden will.. also das heisst kein os verwenden möchte um irgendwie auf
externe dateien zugreifen zu wollenalso ich möchte z.b. sagen wir einen kleinen kreis in der farbe blau als sprite
ablegen, der aus etwa 20 pixel besteht und ich arbeite im mode13h ...
wie gehe ich vor ?
muss ich dann im programmcode jeden pixel selbst definieren ?, also
mir zum beispiel ein 2dimenionales array anlegen aus 20*20 bytes (sofern der kreis einen durchmesser von 20 pixel haben soll) und dann jeden blauen pixel
vom kreis von hand setzen ?
wenn ja, wie würde das etwa dann im code aussehen ?oder kann ich mir da doch das leben mit einem editor ( malprogramm ) einfacher machen ? nur wie verwende ich dann diese pixelinformationen, wenn ich komplett
von jeglichen betriebssystemen unabhängig bleiben möchte..sagen wirs mal so..
die alten AMIGA-spiele haben es ja irgendwie auch hinbekommen..
ich will nich wissen wieviel sprites da pro spiel im programmimage
abgelegt sind...bin für jeden gedankenanreiz dankbar ..
mfg haMMer
-
Moin, Moin...
Wenn Du tatsächlich keine Grafik von Festplatte laden möchtest, ist Deine bereits angedeutete Lösung das Richtige. Du definierst ein Array mit den 8-Bit-Farbwerten Deines Bildes.
bild db 0,0,9,9,9,9,0,0 db 0,9,9,9,9,9,9,0 db 9,9,9,9,9,9,9,9 db 9,9,9,9,9,9,9,9 db 9,9,9,9,9,9,9,9 db 9,9,9,9,9,9,9,9 db 0,9,9,9,9,9,9,0 db 0,9,9,9,9,9,9,0
Nun musst Du die einzelnen Farbwerte in den Grafikspeicher schreiben. Für jede Zeile kannst Du dafür die Stringbefehle des Prozessors nutzen(rep movsb). Dieses Schreiben in den Grafikspeicher hängt natürlich vom Betriebssystem ab. Unter DOS geht das direkt. Unter einem 32-Bit-OS benötigst Du entsprechende Befehle einer Grafikbibliothek, wie z.B. SDL oder DirectX. Beide unterstützen ja direkten Zugriff auf den Grafikspeicher.
Ciao...
-
ey cool !
ich werd mich mal an die arbeit machen und bischen rumprobieren
...danke danke !
wenn in laufe der zeit noch was unklares auftreten sollte, meld ich mich nochmal..
btw.: verdammt, ich hab immernoch kein buch für assembler ..
!
mfg haMMer
[ Dieser Beitrag wurde am 03.06.2003 um 21:24 Uhr von Hammer editiert. ]
-
nochmal ne frage zur ergänzung :
wenn ich jetz ein programm in asm schreibe ohne treiber zu verwenden und ich es
von diskette mit einem selbstgebastelten bootloader starte, kann ich dann
auch die bilddaten einer 8-bit-bitmap binär auf die diskette kopieren und dann
vom programmcode aus diese daten von diskette ins RAM verschieben...?
also ich hätte dann ein komplettes image auf diskette, welches 1. aus dem bootloader besteht, 2. aus dem programmcode und 3. aus den binären bildinformationen ..
is das möglich ?
wenn ja, wie greif ich dann vom code aus auf diese bilddaten zu ?
weil ich müsste ja dann genau die stelle kennen, wo dieses bild auf der diskette abgelegt ist... so wie z.b. der bootloader inerhalb der ersten 512bytes liegtmfg haMMer
-
Moin, Moin...
Natürlich ist das möglich. Der Bootloader lädt den Programmcode in den Speicher. Die Speicheradresse bestimmst Du. Also kannst Du auch die Bilddaten an eine definierte Speicheradresse schreiben. Ich kenne nun nicht die genaue Größe Deines Images, also mach ich mal so ein Beispiel:
Nehmen wir mal an, der Programmcode ist auch 512 Byte lang. Dann liegt der Bootloader im 1. Sektor und der Programmcode in 2. Sektor. Die Bilddaten könntest Du nun in den 3. Sektor schreiben.
Programmcode wird z.B. nach 010000h geladen (1000:0000h). Die Bilddaten könntest Du dann an Adresse 010200h (1000:0200h) schreiben. Dann bräuchtest Du keine FAR-Zeiger, um die Bilddaten zu adressieren.
Wenn die Bilddaten Bestandteil Deines Programmcodes sind, so kannst Du sie einfach im Programm normal adressieren. Sie werden dann ja automatisch mitgeladen.
Ciao...
-
servus nochmal..
also ich hab jetz mal n unterprogramm hinbekommen, welches mir ein bild im
8bit bereich an einer beliebigen stelle aufmalt ..
ich paste hier mal den code und dann wollte ich wissen, ob man den code so lassen kann oder ob das einfacher geht .. :SetSprite proc near push bp mov bp, sp push es push ax push bx push di push cx mov ax, 0A000h mov es, ax mov ax, [bp+4] ; y-koord. mov bx, 320 mul bx add ax, [bp+6] ; x-koord. mov di, ax mov si, [bp+8] ; offset vom bild mov bx, [bp+12] ; länge vom bild sprite: mov cx, [bp+10] ; breite vom bild rep movsb ; schiebe byte von [si] nach [di] cmp bx, 0 je finish ; wenn bx = 0 add di, 320 ; springe auf nächste zeile sub di, [bp+10] ; breite vom bild dec bx ja sprite ; wenn bx > 0 finish: pop cx pop di pop bx pop ax pop es mov sp, bp pop bp ret SetSprite endp
also dieses unterprogramm erhält 5 parameter:
x- und y-koordinate, wo das bild hinkommt (upperleftcorner)
länge vom bild
breite vom bild
und der offset, wo das bild im RAM steht !nur ich hatte das problem, wie ich 2 ineinander verschachtelte "for"-schleifen machen soll, da das cx register zum zählen verwendet wird und ich ja nur eins davon habe.. also musste ich auf cmp umsteigen und mit ja und jb weitere anweisungen geben..
was haltet ihr von dem code..? was kann, sollte und muss man verändern ?
desweiteren wäre ich noch dankbar wenn mir jemand einen gedankenstoss geben kann für folgende zwei probleme :
1. wie schneide ich den hintergrund eines bildes weg, sodass er nur die figur malt und nich das komplette rechteck .. ?
2. durch was wird die geschwindigkeit einer animation festgelegt ?
in hochsprachen hab ich das immer mit einem delay gemacht.. aber
wie muss ich bei asm vorgehen ?mfg haMMer
-
Original erstellt von Hammer:
**1. wie schneide ich den hintergrund eines bildes weg, sodass er nur die figur malt und nich das komplette rechteck .. ?
**Am einfachsten ists, wenn du eine spezielle Farbe als durchsichtig definierst. Dein Programm checkt dann halt, ob das aktuell zu zeichnende Pixel diese Farbe hat, wenn ja, wird das Pixel einfach nicht dargestellt.
-
Original erstellt von Hammer:
**... und dann wollte ich wissen, ob man den code so lassen kann oder ob das einfacher geht ..1. wie schneide ich den hintergrund eines bildes weg, sodass er nur die figur malt und nich das komplette rechteck .. ?
**Wie schon gesagt wurde: eine Farbe als durchsichtig definieren...
Ein Vorschlag: (durchsichtige Farbe ist 00)SetSprite proc near push es ;diverse push gespart... pusha mov bp, sp ;Argumente bei 16+2+2=>20 mov ax, 0A000h mov es, ax mov ax, 320 ;ein mov gespart... mul [word ptr bp+20] ; y-koord. add ax, [bp+22] ; x-koord. mov si, [bp+24] ; offset vom bild mov di, ax mov bx, [bp+28] ; länge vom bild mov bp, [bp+26] mov dx, 320 sub dx, bp sprite: mov cx, bp ; breite vom bild PixelLoop: lodsb test al, al jz NoPixel mov [es:di],al NoPixel: inc di dec cx jnz PixelLoop ;ein cmp; jxx; sub gespart... add di, dx ; springe auf nächste zeile dec bx jnz sprite ; wenn bx != 0 popa ;diverse pop gespart... pop es ret SetSprite endp
Original erstellt von Hammer:
durch was wird die geschwindigkeit einer animation festgelegt ?Eine einfache Moeglichkeit ist, den ueber IRQ0 gesteuerten Zeitgeber bei 0000:046C zu benutzen. Das byte an selbiger Addresse wird ca. 18 mal pro Sekunde inkrementiert.
Du kannst dir natuerlich auch direkt den int8 (IRQ0 handler) greifen (Weiterleitung an den Original handler waere dabei zu empfehlen).
Notfalls kannst du auch die Frequenz, mit der der IRQ0 aufgerufen wird, im PIT aendern. (siehe OS-Dev-Links in FAQ)
-
huch!!
mein assembler sagt bei pusha / popa:
illegal instruction for selected prozessor !
kann das sein dass mein tasm 5.0 den befehl nicht übersetzen kann ?
-
hupsalaaa ..!
hab .386 vergessen ..
d.h. aber dass es den befehl zu beginn nich gab ...
welcher proz-typ ist denn standardmäßig aktiv ?
-
Laut Handbuch ist Standard P8086 (8086 Instructions - wer haette das gedacht
)