Skip to content

Instantly share code, notes, and snippets.

@Frank-Buss
Created April 19, 2022 23:49
Show Gist options
  • Select an option

  • Save Frank-Buss/00a81ba7746cf38500e43ff88c7e8778 to your computer and use it in GitHub Desktop.

Select an option

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
#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