Computerhilfen.de Logo
Forum
Tipps
News
Frage stellen

Pong in C++ (wie macht man Threadsunter DOS ?)

Haloooo ^^...

also... hab ein Problem... ich dacht mal.. ich programmiere mal Das Spiel Pong ! (PingPong mit der 2D grafik, den zwei balken links und rechts).

Ich mach das alles im VideoMode Interrupt 13h (Video-BIOS) also hab ich es als DOS 16Bit Kompiliert (mit OpenWatcom). Die Balken hab ich auch schon gemacht und kann sie beide rauf und Runter schieben.
Nur dabei gibts ein problem. Wenn ich einen runterschiebe... kann nich den anderen nicht Steuern. Nur einer zur zeit. Also muss Multithreading her. (Wenns ne andere moeglichkeit gibt auch bitte sagen !).
Nur wie Multithreading unter 16Bit DOS ? Doch etwa nicht mit WinAPI oder etwa doch ? Und wenn nicht... wie kann ich das in DOS machen... ich meine.. es gibt ne menge spiele die unter DOS gehen.. und halt wunderbar alles auf einmal funktioniert.. und dann noch der Ball in Pong. Der muss ja auch 'eigenstaendig' sein. Also auch ein Thread.. insgesamt 3 Threads !

Das ist mein Bisheriger Code der erstmal funktioniert.. (noch ohne Ball !) :

#include <iostream.h>
#include <conio.h>

using namespace std;

//Diese Variablen sind dazu da um die 'Abstossflaeche' zu bestimmen
//An dieser Flaeche weiss der Ball das er da abgestossen wird.
//die zahl am ende des Namens der Variable bestimmt die Flaeche von-zu
//Also hier von R1 bis R2.
int PhysAreaR1;
int PhysAreaR2;

int PhysAreaL1;
int PhysAreaL2;

//Der 'VideoModus' wird Initialisiert !
void InitVideoMode(void)
{
    //Per Interrupts wird der [url=http://www.computerhilfen.de/fachbegriffe-b-BIOS.html][b]BIOS[/b][/url] Video Modus 13h aufgerufen
    //nach der Zeile 'int 10h' wird die Bildschrimseite gewaehlt
    //(was die 'Bildschirmseite ist hab ich keine ahnung.. ^^)
    _asm
    {                     
        mov  ah, 00h   
        mov  al, 13h   
        int  10h 
        mov  ah, 05h
        mov  al, 01h
        int  10h   
    };
     
}

//Ein Zeichen ausgeben
//Hier Wird nur EIN Zeichen ausgegeben (im Datentyp C-String - char)
void PrintChar(char CHAR, char color)
{
     _asm
    {                     
        mov  ah, 09h   
        mov  bh, 01h   
        mov  cx, 01h
        mov  al, CHAR
        mov  bl, color
        int  10h 
    };
}

//Cursor Position. Ist wirchtig damit man die 'kontrolle' darueber hat
//wo man anfaengt zu schreiben.
void CursorPosition(char X, char Y)
{
     _asm
     {
         mov ah, 02h
         mov bh, 01h
         mov dl, X
         mov dh, Y
         int 10h
     }
}

//Eine PrintPixel ist halt fuer die ausgabe einzelner [url=http://www.computerhilfen.de/fachbegriffe-p-Pixel.html][b]Pixel[/b][/url] da.
void PrintPixel(int X, int Y, char color)
{     
     _asm
     {
         mov ah, 0Ch
         mov bh, 01h
         mov dx, X
         mov cx, Y
         mov al, color
         int 10h
     }
     
     
}

//Globale Variablen. Sodass alle Funktionen auf ein auktuellen
//stand der Koordinaten zugreifen koennen
int gXr;
int gXl;

int gYr;
int gYl;

//Hier wird das die Bewegung der Pongs berechnet !
int Frame(int xr,int xl, int xb, int yb )
{
   int i = 0; //Die Countervariable (Hirarchie 1)
   
   //X-Achse Position wird an die globale variable geschickt.
   gXr = xr;
   gXl = xl;
   
   //Anzeige der jeweiligen Pongs. Hier wird die Position auf dem Bildschirm bestimmt und angezeigt.
   
   char color = (0x0F);
   
   int j = 0; //Countervariablen Hirarchie 2. (Hirarchien Alphabetisch geordnet)
   int k = 0; //dritte H.
   int l = 0; //und vierte Hirarchie
   
   //Hier werden die werte fuer die Y-Achse gesetzt
   int yr = -0x60;
   int yl =  0x40;
   
   //Die Y Koordinaten werden an die Globale Variable 'geschickt'
   gYr = yr;
   gYl = yl;
   
   //Hier wird eine sogenannte 'Absolute Adresse' erzeugt. indem man die beiden werte mal nimmt
   //so erhalten wir fuer jeden [url=http://www.computerhilfen.de/fachbegriffe-p-Pixel.html][b]Pixel[/b][/url] eine art Adresse.
   PhysAreaR1 =(yr + 10) * (xr);
   PhysAreaR2 =(yr) * (xr * 50);
   
   PhysAreaL1 =(yl + 10) * (xl);
   PhysAreaL2 =(yl) * (xl * 50);
   
   //Hier wird der Pong gezeichnet ! :)
    while(1) //Die 'Haupt'-while schleife. i...
    {
      while(1) //j...die zweite
      {
         while(1)//k...die dritte
         {
            if((k == 50) || (k > 50)){break;}
            k++; xr++;
            PrintPixel(xr,yr,color);
         }
         if((j == 10) || (j > 10)){break;}
         j++; yr++;
         PrintPixel(xr,yr,color);
      }
      if((i == 50) || (i > 50)){break;}
      i++; xr--;
      PrintPixel(xr,yr,color);
      while(1)//l...die vierte
      {
        if((i != 50) || (i < 50)){break;}
        if((l == 10) || (l > 10)){break;}
        l++;
        yr--;
        PrintPixel(xr,yr,color); 
      }
    }
    //Alle Counter wieder auf 0 setzen
    i = 0;
    j = 0;
    k = 0;
    l = 0;
    //Der Linke Pong
    while(1) //Die 'Haupt'-while schleife. i...
    {
      while(1) //j...die zweite
      {
         while(1)//k...die dritte
         {
            if((k == 50) || (k > 50)){break;}
            k++; xl++;
            PrintPixel(xl,yl,color);
         }
         if((j == 10) || (j > 10)){break;}
         j++; yl++;
         PrintPixel(xl,yl,color);
      }
      if((i == 50) || (i > 50)){break;}
      i++; xl--;
      PrintPixel(xl,yl,color);
      while(1)//l...die vierte
      {
        if((i != 50) || (i < 50)){break;}
        if((l == 10) || (l > 10)){break;}
        l++;
        yl--;
        PrintPixel(xl,yl,color); 
      }
    }
   
    return 1;
}


void DeletePong()
{
    int i = 0;
    int j = 0;
    int k = 0;
    int l = 0;
   
    int xr = gXr;
    int xl = gXl;
   
    int yr = gYr;
    int yl = gYl;
   
    char color = (0x00); //schwarz
   
    //Das ist das gleiche verfahren wie beim Zeichnen des Pongs.. nur mit schwarz.
    //Sodass es "wie geloescht" ausseiht
    while(1) //Die 'Haupt'-while schleife. i...
    {
      while(1) //j...die zweite
      {
         while(1)//k...die dritte
         {
            if((k == 50) || (k > 50)){break;}
            k++; xr++;
            PrintPixel(xr,yr,color);
         }
         if((j == 10) || (j > 10)){break;}
         j++; yr++;
         PrintPixel(xr,yr,color);
      }
      if((i == 50) || (i > 50)){break;}
      i++; xr--;
      PrintPixel(xr,yr,color);
      while(1)//l...die vierte
      {
        if((i != 50) || (i < 50)){break;}
        if((l == 10) || (l > 10)){break;}
        l++;
        yr--;
        PrintPixel(xr,yr,color); 
      }
    }
    //wieder Counter auf 0 setzten
    i = 0;
    j = 0;
    k = 0;
    l = 0;
    while(1) //Die 'Haupt'-while schleife. i...
    {
      while(1) //j...die zweite
      {
         while(1)//k...die dritte
         {
            if((k == 50) || (k > 50)){break;}
            k++; xl++;
            PrintPixel(xl,yl,color);
         }
         if((j == 10) || (j > 10)){break;}
         j++; yl++;
         PrintPixel(xl,yl,color);
      }
      if((i == 50) || (i > 50)){break;}
      i++; xl--;
      PrintPixel(xl,yl,color);
      while(1)//l...die vierte
      {
        if((i != 50) || (i < 50)){break;}
        if((l == 10) || (l > 10)){break;}
        l++;
        yl--;
        PrintPixel(xl,yl,color); 
      }
    }
}

//main() funktion
int main()
{
    //X & Y Cordinaten fuer die Frame funktion
    int Xr = -0x40;
    int Xl = -0x40;
   
    InitVideoMode();
    int i;
    Frame(Xr,Xl,0,0);
   
    unsigned int ch;
    while(1)
    {
      ch = getch();
      DeletePong();
      if((ch == 224) || (ch == 0))
      {
        unsigned int ch2 = getch();
        //DOWNs
        if(ch2 == 72)
        {
           
            Xr--;
            if(Xr == -0x60){Xr = Xr + 1;}
            else if(Xr ==  0x20){Xr = Xr - 1;}
            else{Xr = Xr;}
            Frame(Xr,Xl,0,0);
           
        }
        //UP
        else if(ch2 == 80)
        {
            Xr++;
            if(Xr == -0x60){Xr = Xr + 1;}
            else if(Xr ==  0x20){Xr = Xr - 1;}
            else{Xr = Xr;}
            Frame(Xr,Xl,0,0);
        }
        else
        {
            Frame(Xr,Xl,0,0);
        }
      }
      //ENTER = char 13
      else if(ch == 13)
      {
           Frame(Xr,Xl,0,0);
           break;
      }
      else if((ch == 's') || (ch == 'S'))
      {
           Xl++;
           if(Xl == -0x60){Xl = Xl + 1;}
           else if(Xl ==  0x20){Xl = Xl - 1;}
           else{Xl = Xl;}
           Frame(Xr,Xl,0,0);
      }
      else if((ch == 'w') || (ch == 'W'))
      {
           Xl--;
           if(Xl == -0x60){Xl = Xl + 1;}
           else if(Xl ==  0x20){Xl = Xl - 1;}
           else{Xl = Xl;}
           Frame(Xr,Xl,0,0);
      }
      else
      {
          Frame(Xr,Xl,0,0);
      }
    }
   
    return 0;
}

 

Ich bin fuer jede hilfe dankbar !

MFG
TOMEK 
« Letzte Änderung: 23.03.08, 20:28:00 von Sniper-Hawk »

Antworten zu Pong in C++ (wie macht man Threadsunter DOS ?):

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Hi |

Ohne mir das jetzt alles durchgelesen zu haben:

DOS ist kein Multitasking-System. Es gibt dort nur 1 Prozess zu einer Zeit, also vergiss das mit dem echten Multithreading. Da wirst du selber etwas derartiges bauen müssen. Multitasking-Systeme haben zur Task-Umschaltung einen sog. Scheduler, der nach unterschiedlichen Mustern die Threads/Prozesse priorisiert und zwischen ihnen umschaltet. Vielleicht kannst du sowas ansatzweise implementieren (wobei es sicher kein lupenreines Multitasking bei dir werden wird, da dort gekapselte Speicherbereiche etc. auch noch eine Rolle spielen).

Viel Erfolg!

greez 8)
JoSsiF

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

dankee JoSsiF.  :D

hmm..okk....
Also vergess ich erstmal Multitasking/threading... ^^

Aber. In den DOS zeiten kannten sie ja auch kein Multitasking... erst ab der einfuehrung von Prozessoren mit PMode und all dem zeugs was das Multitasking von der Hardware aus auch unterstuetzte, konnte man das durchsetzten. Aber DOS ist ja in den RealMode zeiten aufgewachsen.. da war nix mit multitasking..^^ (korriegiert mich wenn ich mich irre)

...

Also mussten sie das anders machen.
...
Etwas was halt zwei tasten auf einmal lesen kann... Und noch eine andere Operation ausgefuert werden kann.
Ich hab mir gedacht. Das es wohl an der getch() funktion liegen muss. Da sie ja auf ein Tastendruck WARTET.
Und da koennte mein problem sein.
Es waere bessere eine funktion zuhaben die sich sofort beendet falls im speicher (TastaturPort oder aehnliches) kein Scanncode (oder aehnlcihes ^^) vorhanden ist. So koennte ich den Ball fliegen lassen und dabei auch die tastendruecken. (der Scanncode muss dan maximal einmal pro 'cyklus' laufen. damit der ball chance hat sich ueberhaupt zu bewegen)
Vll muesste ich eine 'eigene' initiative versuchen. Indem ich vll dies Direkt tuhe ueber Ports oder Interrupts....

Falls ich in die falsche richtung denk... immer auf ne antwort hilfe offen...

MFG
TOMEK

  

« Letzte Änderung: 24.03.08, 14:32:13 von Sniper-Hawk »

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button
Aber DOS ist ja in den RealMode zeiten aufgewachsen.. da war nix mit multitasking..^^ (korriegiert mich wenn ich mich irre)

Genau. Und um diese Einschränkung zu umgehen, gab's IMHO damals die DOS/4GW-Runtime, die viele Spiele einsetzten. Vielleicht hilft dir das ja bei der Recherche ;)

greez 8)
JoSsiF

Warum Threads?

Eigentlich wird das so gemacht

(A bisl pseudo-code)

while(1)
{
   if( kbhit() )
   {
      char c = getch();
      if( c == ENDE )
          break;
      execute( c );
   }
   RenderFrame();
}

Fazit: Pollen statt warten.

PS: Es gibt in C Zählschleifen.

Der folgende Code ist ... seltsam.
         while(1)//k...die dritte
         {
            if((k == 50) || (k > 50)){break;}
            k++; xr++;
            PrintPixel(xr,yr,color);
         }


So ist das besser (man sieht zB die Abbruchbedingung besser):
  for( ; k < 50; ++k, ++xr )
  {
     PrintPixel(xr,yr,color);
  }

« Prog nicht in der TaskleisteLinux Anwendung auf Windows XP ausführen????????? »
 

Schnelle Hilfe: Hier nach ähnlichen Fragen und passenden Tipps suchen!

Fremdwörter? Erklärungen im Lexikon!
DOS
Die Abkürzung DOS steht für "Disk Operating System". Dies ist ein System aus dem Hause Microsoft und war der Vorgänger von Windows. Maus und Multimedia war...

Quellcode
Ein Quellcode, auch als Quelltext bekannt, bezeichnet den unkompilierten Programm-Code einer Software. Quell- oder Programm-Code ist der auch für Menschen lesbare Co...

Unicode
Unicode ist ein international anerkannter Standard, der als universeller Zeichencode ("Universal Code") dient und durch das Unicode-Konsortium entwickelt und verwaltet wi...