Zeichnen im DOS-Mode
-
Hallo. Wie kann ich im DOS - Mode Punkte, Linien, Kreise und Quadrate zeichnen? Wenn ihr noch wißt, wie man die Farbe der Punkte... verändern kann, dann schreibt dies bitte auch dazu.
Ich wäre froh, wenn es mit einem Beispiel-Programm erklärt würde, dass man dann genau so ausführen kann.
Bitte helft mir.
Danke im voraus.------------------
Squolly
-
Sorry, habe hier gelöscht weil ich den Beitrag ins Archiv schieben will.
[Diese Nachricht wurde von class CMarcus am 20-01-2001 editiert.]
-
Wer redet denn hier von Zugriffsfehlern, was denkst Du denn wie die Daten von Deinem C-Programm in den Speicher der Grafikkarte gelangen.
Das einfachtste was ich Dir anbieten kann wäre hier Mode13. Du hast dann eine Auflösung von 320x200 Punkten bei 256 Farben zur Verfügung. Die Startadresse für den Videospeicher im BIOS lautet 0xa000. Die Farben werden über eine Palette gesetzt, die dann 768 Bytes lang ist und sich in der Form RGBRGBRGBRG.. (drei Bytes bilden immer eine Farbe) zusammensetzt. Wenn Du keine neue Palette generieren willst, hast Du in den Farben 0 bis 15 die bekannten Farben aus der Standard-DOS-Palette zur Verfügung.Alles was Du tun musst, ist in diesen Modus umschalten (Aufruf von Interupt 0x10 mit AX=0x13) und Dir eine Setpixel-Routine bauen. Beachte das eine Zeile 320 Pixel hat, also ist die Transformation von Punkt(X,Y) zu Speicher wie folgt zu berechnen: 320*X+Y .
Allerdings weis ich nicht was Dir lieber ist: willst Du es in Assembler oder in C schreiben ??? ich habe beides schon geschrieben, wenn Du willst dann Poste ich Dir zurück wie das geht.
MfG
-
#pragma inline asm .386p #include <io.h> #include <dos.h> #include <stdio.h> #include <conio.h> #include <fcntl.h> #include <process.h> #define byte unsigned char #define word unsigned int #define dword unsigned long void setpixel_in_c ( word xpos, word ypos, byte color ) { char *screen=(char*)0xa0000000; *(screen+320*ypos+xpos)=color; } void setpixel ( word xpos, word ypos, byte color ) { asm push [0xa000] asm pop es asm mov di,[xpos] asm mov bx,[ypos] asm mov al,[color] asm mov cx,bx asm shl bx,8 asm shl cx,6 asm add bx,cx asm add di,bx asm stosb } void copyscreen ( word dest, word source ) { asm mov ds, [source] asm mov es, [dest] asm xor si, si asm mov di, si asm mov cx, 16000 asm rep movsd } void clearscreen ( word dest ) { asm push [dest] asm pop es asm xor di, di asm mov cx, 16000 asm xor eax,eax asm rep stosd } void mode13exit ( void ) { asm mov ax, 0x03 asm int 0x10 } void mode13init ( void ) { asm mov ax, 0x13 asm int 0x10 } void setpal ( char palette[] ) { word counter; outp(0x3c8,0); for(counter=0;counter<=768;counter++) outp(0x3c9,palette[counter]); } void loadtga ( char *name, char *pixels, char palette[] ) { byte file_handle,temp_col; word counter; if ((file_handle =open(name, O_RDONLY | O_BINARY)) == -1) { printf("can't open %s\n",name); exit(1); } read(file_handle, pixels, 18); read(file_handle, palette, 768); for(counter=0;counter<=766;counter+=3) { temp_col=palette[counter]>>2; palette[counter+1]=palette[counter+1]>>2; palette[counter]=palette[counter+2]>>2; palette[counter+2]=temp_col; } for(counter=1;counter<=200;counter++) read(file_handle, (pixels+64000-counter*320), 320); close(file_handle); } void loadpcx ( char *name, char *pixels, char palette[] ) { int handle; word i,j,k; byte p,q; i=0;j=0;p=0;k=0; if ((handle =open(name, O_RDONLY | O_BINARY)) == -1) { printf("can't open %s\n",name); exit(1); } lseek(handle,128,SEEK_SET); do { read(handle,&p,1); if((p&0xc0)==0xc0) {q=(p&0x3f);read(handle,&p,1);for(k=0;k<q;k++){*(pixels+j)=p;j++;}} else {*(pixels+j)=p;j++;} } while(j<64000); lseek(handle,-768,SEEK_END); for(i=0;i<768;i++) {read(handle,&p,1);palette[i]=p>>2;} close(handle); }
Eigentlich kann man alles in C programmieren, aber ich hatte immer das Problem, dass ich den Mode13 nicht initialisieren kann, ohne eine Assemblerbefehl zu nehmen. Es sei denn, jemand weiss, wie man den Interupt mit einem C-Befehl anspringen kann.
Die beiden Bild-Loader nehmen nur Bilder, die 320X200 Pixel sind und 256 Farben haben.
Die Setpixel-Routine in C sieht zwar kurz und bündig aus, aber wer weiss was der Compiler draus macht? Auf jeden Fall ist die in Assembler geschriebene schneller (ich glaube weniger als 20 Taktzyklen auf 'nem 486-er), da ich die Multiplikation (320*y) in zwei Bitverschiebungen umwandle.Wen es interessiert, das ganze habe ich unter Borland C-Compiler 3.x unter MS-Dos geschrieben (aber mit Watcom hab' ich es auch schon unter Win9x compiliert).
MfG
Edit by SideWinder: Code-Tags eingefügt.
[ Dieser Beitrag wurde am 06.05.2002 um 19:28 Uhr von SideWinder editiert. ]