Created
April 19, 2022 23:49
-
-
Save Frank-Buss/00a81ba7746cf38500e43ff88c7e8778 to your computer and use it in GitHub Desktop.
star scroller effect program for Watcom C and DOS, which I wrote in 1995
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <conio.h> | |
| #include <time.h> | |
| #include <stdlib.h> | |
| extern void waitvsync(); | |
| extern unsigned short setvideomode(); | |
| extern void restorevideomode(unsigned short old); | |
| extern void setcolor(unsigned short farbe); | |
| extern void setpixel(unsigned short x,unsigned short y); | |
| #pragma aux waitvsync= /* auf Synchronisation warten */ \ | |
| " mov dx,03dah "\ | |
| " l1: in al,dx "\ | |
| " test al,8 "\ | |
| " jnz l1 "\ | |
| " l2: in al,dx "\ | |
| " test al,8 "\ | |
| " jz l2 "\ | |
| modify exact [ax dx] | |
| #pragma aux setvideomode= /* alter Videomode wird in ax zurueckgeliefert */ \ | |
| " mov ah,0fh "\ | |
| " int 10h "\ | |
| " xor ah,ah "\ | |
| " push ax "\ | |
| " mov ax,10h "\ | |
| " int 10h "\ | |
| " mov dx,03ceh " /* graphics controller */ \ | |
| " mov ax,0f01h " /* enable set/reset-Register: Latches mit Reg.0 verkn.*/ \ | |
| " out dx,ax "\ | |
| " mov al,0003h " /* function select-Register: Bits ersetzen */ \ | |
| " out dx,al "\ | |
| " mov al,0005h " /* mode-Register: Lesemodus 0, Schreibmodus 0 */ \ | |
| " out dx,al "\ | |
| " pop ax " /* Rueckgabewert in AX=alter Videomodus */ \ | |
| modify exact [ax bx cx dx] | |
| #pragma aux restorevideomode= /* Videomodus wird in ax uebergeben */ \ | |
| " int 10h "\ | |
| parm [ax] modify exact [ax bx cx dx] | |
| #pragma aux setcolor= /* Farbe wird in ax uebergeben */ \ | |
| " mov dx,03ceh " /* graphics controller */ \ | |
| " mov ah,al " /* Farbe nach ah */ \ | |
| " mov al,0 " /* set/reset-Register */ \ | |
| " out dx,ax "\ | |
| parm [ax] modify exact [ax dx] | |
| #pragma aux setpixel= /* x-Koordinate wird in cx, y-K. in si uebergeben */ \ | |
| " mov dx,03ceh " /* graphics controller */ \ | |
| " mov bx,cx " /* x-Koordinate kopieren */ \ | |
| " and cl,7 "\ | |
| " mov ah,128 "\ | |
| " shr ah,cl " /* Pixelposition errechnen */ \ | |
| " mov al,8 " /* bit mask-Register */ \ | |
| " out dx,ax "\ | |
| " shr bx,1 " /* x-Koordinate geteilt durch 8 */ \ | |
| " shr bx,1 "\ | |
| " shr bx,1 "\ | |
| " mov cx,si "\ | |
| " shl cx,1 "\ | |
| " shl cx,1 " /* y-Koordinate mal 4 */ \ | |
| " add cx,si " /* plus y-Koordinate, macht y*5 */ \ | |
| " shl cx,1 "\ | |
| " shl cx,1 "\ | |
| " shl cx,1 "\ | |
| " shl cx,1 " /* Ergebnis mal 16, macht 5*16=80 */ \ | |
| " add bx,cx " /* zum x-Offset addieren */ \ | |
| " mov ax,0a000h "\ | |
| " mov es,ax " /* Grafiksegment */ \ | |
| " or es:[bx],al " /* lesen fuer Latches laden und mit Farbe schreiben */ \ | |
| parm [cx][si] modify exact [ax bx cx dx si es] | |
| class Star { | |
| private: | |
| struct one_star { | |
| long x; // aktuelle x-Position des Sterns *256 | |
| int y; // aktuelle y-Position des Sterns | |
| int speed; // Sterngeschwindigkeit | |
| unsigned char color; // Sternfarbe | |
| }; | |
| one_star *stars; // Zeiger auf Sternenstruktur | |
| int anzahl; // Anzahl Sterne | |
| int xmax; // Bildschirmbreite | |
| public: | |
| // Konstruktor mit teilweise vorinitialisierten Parametern | |
| Star(int anz,int min_speed=10,int max_speed=2000,int xm=639,int ym=349); | |
| ~Star(); // Destruktor, gibt Speicher wieder frei | |
| void update(); // Naechsten Sternenhimmel anzeigen | |
| }; | |
| Star::Star(int anz,int min_speed,int max_speed,int xm,int ym) { | |
| stars=new one_star[anz]; // erzeugt dynamisch ein Array of one_star | |
| for (int c=0;c<anz;c++) { | |
| // long(rand()) bedeutet, dass erst die Randfunktion ausgefuehrt wird. | |
| // Die liefert aber ein short (16-Bit), deshalb muss durch eine | |
| // explizite Typumwandlung daraus ein long (32-Bit) gemacht werden, | |
| // damit es mit xm oder ym multipliziert werden kann, ohne das | |
| // ein Zahlenueberlauf passiert | |
| stars[c].x=long(rand())*xm/RAND_MAX<<8; // Zufalls-x-Position setzen | |
| stars[c].y=long(rand())*ym/RAND_MAX; // Zufalls-y-Position setzen | |
| stars[c].speed=long(rand())*(max_speed-min_speed)/RAND_MAX+min_speed; | |
| // Farbe entsprechend der Geschwindigkeit setzen | |
| stars[c].color=(stars[c].speed-min_speed)*9/max_speed; | |
| } | |
| anzahl=anz; // private-Variablen initialisieren | |
| xmax=xm; | |
| } | |
| Star::~Star() { | |
| delete stars; // dynamisches Array wieder freigeben | |
| } | |
| void Star::update() | |
| { | |
| // statisches Array fuer Farben | |
| unsigned char const co[8]={9,3,12,13,7,10,11,15}; | |
| for (int c=0;c<anzahl;c++) { | |
| long x=stars[c].x; // Variable x:long erzeugen und x-Koordinate lesen | |
| int y=stars[c].y; // dasselbe mit y:int | |
| setcolor(0); | |
| setpixel(x>>8,y); // bedeutet: setpixel(x/256,y) | |
| setcolor(co[stars[c].color]); | |
| x-=stars[c].speed; // x-Koordinate aendern | |
| if (x<0) x+=long(xmax)<<8; // scrollt links raus und rechts rein | |
| // bedeutet: stars[c].x=x; setpixel(stars[c].x>>8,y); | |
| setpixel((stars[c].x=x)>>8,y); | |
| } | |
| } | |
| // Hauptprogramm | |
| void main() { | |
| // alten Videomodus holen neuen initialisieren | |
| unsigned short mode=setvideomode(); | |
| srand(time(NULL)); // Zufallsgenerator initialisieren | |
| Star star(200); // Instanz der Klasse Star anlegen | |
| while (!kbhit()) { // solange keine (das '!') Taste gedrueckt wurde | |
| waitvsync(); // Synchronisierung | |
| star.update(); // Naechste Position | |
| } | |
| restorevideomode(mode); // alten Videomodus wiederhestellen | |
| // Taste aus Tastaturpuffer lesen, falls Sondertaste, zweiten Code lesen | |
| if (getch()==0) getch(); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment