MIDI/WAV File aus Consolenprogramm ausgeben

worstcase

Grünschnabel
Als kleine Projektarbeit an der Technikerschule müssen wir verschiedene Programme in C++ erstellen, Nach zu hohen Hardwarekosten für eine Wetterstation habe ich mich für ein Spiel entschieden (TRON) das Grundlegende Spiel läuft auch schon. Jetzt würde ich gerne noch ein bissel Sound einbauen. Kann aber in der MSDN nichts passendes finden, da ich ausschließlich für die Konsole programmiere.

Zweite Frage
Ich kann zurzeit nur Bitmap mit einer größer von maximal 70*70 Pixeln laden alles darüber hinaus wird merkwürdig. Vieleicht hat jemand eine Idee.

Über euere Hilfe wäre ich sehr dankbar. Ach ja ich in blutiger Anfänger C++ erst seit Februar 6 Stunden die Woche.

Code:
#include <math.h>
#include <ctime> //Zufallsgenerator
#include <string> //Spielerreien mit Text
#include <iostream> //Ein und Ausgabe von Text
#include <windows.h> //Grafik
#include <fstream> //Datei Operationen
#include <conio.h> //Grafik

using namespace std;

//allgemeine Funktionen
int zufall(int low, int high); //Zufalsszahl zwischen low und high
int Taste();
void warten(); //warten auf enter
void initrand(); //init des Zufallszahlengenerators

//Grafikfunktionen
void cls(HDC fenster); //Clear Screen
void loadbmp(HDC fenster, int posx, int posy, int sizex, int sizey,char* datei);//lädt eine Bitmapdatei max Size 70*70
void boxfilled(HDC fenster, int posx, int posy, int dimx, int dimy, int cr, int cg, int cb);
void box(HDC fenster, int posx, int posy, int dimx, int dimy, int cr, int cg, int cb);

//Diese beiden Funktionen stammen nicht von mir wurden nur angepasst
void line(HDC fenster, int x1, int y1, int x2, int y2, int cr, int cg, int cb);
void circle(HDC fenster, int xCenter,int yCenter,int radius, bool filled,int cr, int cg, int cb);


//Zusatzfunktionen
void intro(HDC fenster);



int main()
{
	int i, posx,posy,tpa,tpb,posxb,posyb,pahit,pbhit;
	int feld[640][300];

	//Grafikausgabe in der Konsole initalisieren
	HWND hWnd = FindWindow( "ConsoleWindowClass", NULL );
	if( !hWnd )

	return 1;
	HDC hDC = GetDC( hWnd );
	if( !hDC )
	   return 1;
	//Konsole ist nun bereit für Grafik

	intro(hDC);

	//Datenfeld für Kollisionserkennung vorbereiten
	for(int px=0;px<640;++px)
	{
		for(int py=0;py<300;++py)
		{
			feld[px][py]=0;
		}
	}
	
	box(hDC,20,20,500,200,255,255,2); //Spielfeld zeichnen
	
	posx=100; //startposition P1
	posy=100; //startposition P1
	posyb=120; //startposition P2
	posxb=120; //startposition P2
	pahit=0; //Kollision P1
	pbhit=0; //Kollision P2
	tpa=77; //Taste P1
	tpb=100; //Taste P2h

	//Grundlegende Funktion für Spiel TRON 
    
	do
		{
			
			if (_kbhit()) i=Taste(); //Nach Tastendruck Taste abrufen



			//Logik Spieler 1
			if (i==77||i==75||i==72||i==80) tpa=i;

			if (tpa==77) ++posx;
			if (tpa==75) --posx;
			if (tpa==72) --posy;
			if (tpa==80) ++posy;
			
			SetPixel(hDC,posx,posy,RGB(244,0,255)); //Setzte Pixel auf Spielfeld

			if (feld[posx][posy]==1||posx<21||posx>519||posy<21||posy>219) pahit=1; //Kollisonserkennung P1
			if (feld[posx][posy]==0) feld[posx][posy]=1;
			

			//Logik Spieler 2
			if (i==97||i==100||i==115||i==119) tpb=i;

			if (tpb==97) --posxb;
			if (tpb==100) ++posxb;
			if (tpb==115) ++posyb;
			if (tpb==119) --posyb;

			SetPixel(hDC,posxb,posyb,RGB(0,100,255));
			
			if (feld[posxb][posyb]==1||posxb<21||posxb>519||posyb<21||posyb>219) pbhit=1;
			if (feld[posxb][posyb]==0) feld[posxb][posyb]=1;

			//Bewegung verlangsammen
			Sleep(10);
		
		}while(i!=113&&pahit==0&&pbhit==0); //bei drücken von q oder Kollision ende
		


		boxfilled(hDC,20,20,501,201,0,0,0); //Spielfeld löschen
		
		if (pahit==1) cout<<"\n\n\n\n        Player 1 verliert  Player2 gewinnt\n\n";
		if (pbhit==1) cout<<"\n\n\n\n        Player 2 verliert  Player1 gewinnt\n\n";
		
		warten();

		return 0;
}

int zufall(int low, int high)
{
  if(low>high) swap(low,high);
  return rand()%(high-low+1)+low;
}

void warten()
{
  cout << "\n\nPress \"ENTER\" to continue";
	fflush(stdin);
	getchar();
}

void cls(HDC fenster)
{
		system("CLS");
}

void initrand() {srand( (unsigned)time( NULL ) );}

void boxfilled(HDC fenster, int posx, int posy, int dimx, int dimy, int cr, int cg, int cb)
{
	for (int i=posx;i<dimx+posx;++i)
	{
		for (int a=posy;a<dimy+posy;++a)
		{
			SetPixel(fenster,i,a,RGB(cr,cg,cb));
		}
	}
}

void box(HDC fenster, int posx, int posy, int dimx, int dimy, int cr, int cg, int cb)
{
	int i;
	for (i=posx;i<dimx+posx;++i) SetPixel(fenster,i,posy,RGB(cr,cg,cb));
	for (i=posx;i<dimx+posx;++i) SetPixel(fenster,i,posy+dimy,RGB(cr,cg,cb));
	for (i=posy;i<dimy+posy;++i) SetPixel(fenster,posx,i,RGB(cr,cg,cb));
	for (i=posy;i<dimy+posy;++i) SetPixel(fenster,posx+dimx,i,RGB(cr,cg,cb));
}

void line(HDC fenster, int x1, int y1, int x2, int y2, int cr, int cg, int cb)
{
    int i, deltax, deltay, numpixels;
    int d, dinc1, dinc2;
    int x, xinc1, xinc2;
    int y, yinc1, yinc2;

    deltax = abs(x2 - x1);
    deltay = abs(y2 - y1);

    if(deltax >= deltay) {
        numpixels = deltax + 1;
        d = (2 * deltay) - deltax;
        dinc1 = deltay << 1;
        dinc2 = (deltay - deltax) << 1;
        xinc1 = 1;
        xinc2 = 1;
        yinc1 = 0;
        yinc2 = 1;
    } else {
        numpixels = deltay + 1;
        d = (2 * deltax) - deltay;
        dinc1 = deltax << 1;
        dinc2 = (deltax - deltay) << 1;
        xinc1 = 0;
        xinc2 = 1;
        yinc1 = 1;
        yinc2 = 1;
    }

    if(x1 > x2) {
        xinc1 = -xinc1;
        xinc2 = -xinc2;
    }
    if(y1 > y2) {
        yinc1 = -yinc1;
        yinc2 = -yinc2;
    }

    x=x1;
    y=y1;

    for(i = 1; i < numpixels; i++) {
        SetPixel(fenster,x,y,RGB(cr,cg,cb));

        if(d < 0) {
            d = d + dinc1;
            x = x + xinc1;
            y = y + yinc1;
        } else {
            d = d + dinc2;
            x = x + xinc2;
            y = y + yinc2;
        }
    }
} 

void circle(HDC fenster, int xCenter,int yCenter,int radius, bool filled,int cr, int cg, int cb)
 {
    int x = 0;
    int y;
    int p;

    if(!filled) {
        y = radius;
        p = 3 - 2 *radius;
        
        while(x<=y) {
            
			SetPixel(fenster,xCenter+x,yCenter+y,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-x,yCenter+y,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter+x,yCenter-y,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-x,yCenter-y,RGB(cr,cg,cb));

			SetPixel(fenster,xCenter+y,yCenter+x,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-y,yCenter+x,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter+y,yCenter-x,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-y,yCenter-x,RGB(cr,cg,cb));

            if(p < 0) {
                p += 4 * x++ + 6;
            } else {
                p += 4 * (x++ - y--) + 10;
            }
        }
 
		} else {
        for(int fill = radius; fill > 0; fill--) {
         x = 0;
         y = fill;
         p = 3 - 2 *fill;

         while(x<=y) {
            
			SetPixel(fenster,xCenter+x,yCenter+y,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-x,yCenter+y,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter+x,yCenter-y,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-x,yCenter-y,RGB(cr,cg,cb));

			SetPixel(fenster,xCenter+y,yCenter+x,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-y,yCenter+x,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter+y,yCenter-x,RGB(cr,cg,cb));
			SetPixel(fenster,xCenter-y,yCenter-x,RGB(cr,cg,cb));


            if(p < 0) {
                p += 4 * x++ + 6;
            } else {
                p += 4 * (x++ - y--) + 10;
            }
        }
    }
    }
}

void loadbmp(HDC fenster, int posx, int posy, int sizex, int sizey, char* datei)
{
	ifstream in(datei);
	if (!in.is_open())
		cout << "Datei existiert nicht." << endl;
	else
	{
		char Puffer[55];  
		in.read(Puffer,52); //Header der bmp Datei entfernen
		for (int x=sizex;x>0;--x)
		{
			in.read(Puffer,2); //Nach jeder Grafikzeile kommen 2 byte Müll die werden gelöscht
			for(int y=0;y<sizey;++y)
			{
				in.read(Puffer,3);
				SetPixel(fenster,y+posy,x+posx,RGB(Puffer[2],Puffer[1],Puffer[0]));
			}
		}
		in.close();
	}
}

void intro(HDC fenster)
{
	cout << "TRON V0.000000001b\n\n\n";
	cout << "Proof of Concept Version\n\n\n";
	cout << "Steuerung Player1 -> Cursortasten\n";
	cout << "Steuerung Player2 -> W A S D\n\n";
	cout<<  "druecke q waerend des Spiels zum beenden";
	
	warten();
	cls(fenster);

}

int Taste()
{
  int x;
  x=getch();
  if(x==224) x=getch();
  return x;
}
 
Für rudimentäre Soundausgabe düfte sich PlaySound eignen( Funktionsweise siehe MSDN)

Das mit dem Bitmaps könnte damit zusammenhängen dass die Konsole nur 70*70 Pixel groß ist.
Evtl hilfts wenn du dir die Pixel in ein Array speicherst und dann verkleinerts.

Beim Überfliegen deines Codes noch eine Kleinigkeit:
den Code:
Code:
for(int px=0;px<640;++px)
{
	for(int py=0;py<300;++py)
	{
		feld[px][py]=0;
	}
}
kannst du ersetzen durch:
Code:
memset(feld, 0, 640*300);
ich weiß nicht obs schneller ist, aber auf jeden Fall kürzer ;)
 
hallo,

Ersteinmal vielen Dank für deine Antwort.
Die Auflösung der Konsole beträgt 640*300 Pixel, ich kann auch mehrere Bitmaps laden, und an unterschiedlichen Stellen plazieren, nur leider dürfen die einzelen nicht größer als 70*70 Pixel sein, könnte es mit dem Einlesepuffer zusammenhängen.

Gruß
 
Ich kenn mich mit dem bmp Format jetzt nicht so direkt aus, aber wie wärs wenn du mal
den Header, statt ihn weg fallen zu lassen, mit parst und dann interpretierst?

Vielleicht steht da etwas über Auflösung, 16/24/32 Bit usw drin?
 
Hallo,
danke für deine Antwort.
Da ich nur 24Bit Bitmaps verwende, ist mir der Aufbau des Header egal.
Die Daten liegen so (bei 24Bit Bitmap) eigentlich passend vor. Mit kleineren Bitmaps haut es ja hin.
Mit Hexeditor angeschaut verändert sich die Struktur einer Bitmap(24Bit -> 3Byte für die Farbe RGB) bei verschieden Grössen nicht.

Aufbau:
Header 52 Byte es folgt die erste Zeile der Grafik hierbei werden pro Bildpunkt 3 Bytes verwendet bei Zeilenende 2 byte "0" folgende Zeilen gleicher Aufbau.
Bedeutet wenn ich die Dimensionen kenne, kann ich den Inhalt gut mit 2 for Schleifen auslesen und die Bildpunkte direkt setzten.

Meine Vermutung ist ja das der "ifstring" Probleme mit der Dateigrösse hat, alle Versuche den Puffer zu erhöhen sind gescheitert, ich werde aus der MSDN nicht wirklich schlau, was das angeht.
 
Zurück