Mauszeiger mit der SDL



  • Hi Leute!

    Ich beschäftige mich derzeit mit meinem ersten kleinen Spielprojekt und bastel mir grad die Grundlagen zusammen... Dazu benutze ich die SDL, da in einem Buch ein paar Grundlagen dazu erklärt wurden und ein passendes kleines Framework schon vorprogrammiert dabei war. Da ich an der Implementierung einer Audio-Klasse erstmal gescheitert war, dachte ich mir: "Hey, versuchen wir einfach mal die Maus zum laufen zu bringen..." 😃

    So weit, so gut - ich hab mir dann eine Klasse CMouse gebastelt, die einen neuen Mauszeiger erzeugen soll... Dazu hab ich den Originalmauszeiger einfach unsichtbar machen (ist ja ganz einfach mit der Funktion ShowCursor() ) und ein Sprite als Cursor verwendet. Funktioniert tadellos soweit. 🙂

    Doch jetzt hab ich 2 Fragen: Ist mir schon zu Beginn aufgefallen, nämlich ist bei mir der Originalcursor nie sichtbar... Auch wenn ich ihn per Funktion explizit auf visible stelle, der Cursor taucht nie auf. Der Sprite funktioniert und bewegt sich mit den richtigen Mausdaten mit. Kann auch sein, dass ich mit der Maske gepfuscht hab...

    Und dann kommt da meine zweite Frage ins Spiel:
    Ich rufe in meiner Callbackfunktion immer ab, ob die Maus bewegt wurde. Wenn das der Fall ist, verzweige ich und übergebe den Event einer Funktion, die wiederum den Sprite am Bildschirm verschiebt. Jedoch findet da eine extreme Verzögerung statt und der Mauszeiger bewegt sich ziemlich schleppend über den Bildschirm... Hab ich da vllt. etwas falsch verstanden, in Richtung des MouseEvents vielleicht?

    Falls ihr den Code braucht, sagt mir bitte welche Daten relevant sind. 😉



  • Kann auch sein, dass ich mit der Maske gepfuscht hab...

    was meinst du mit "maske"?

    Und dann kommt da meine zweite Frage ins Spiel:

    dafür kann alles mögliche die ursache sein.
    nimm markante codeteile(zb die die für das blitten verantwortlich sind) raus und schau, wie sich die performance deines programms verändert um den flaschenhals zu finden.



  • @Maske: Es gibt 2 Arrays, die mit Werten gefüllt werden. Diese Werte werden dann verglichen und per Bool-Operatoren ergeben sich verschiedene Eigenschaften des Mauszeigers - bzw. der Pixel.

    Zum Beispiel ergibt der Wert 0 mit der Maske 1 einen weißen Pixel. Praktisch sieht das so aus:

    0 0 0 0 0 0 0 0 -> Data
    0 0 1 1 1 0 0 0 -> Mask
    - - X X X - - -

    Die X stehen für einen weißen Bildpunkt, die Striche für einen transparenten Bildpunkt (die Kombinationen 0-0). Mit der Maske kann man sich nun den Mauscursor basteln. 😉

    Btw: Was meinst du mit "blitten"?



  • Btw: Was meinst du mit "blitten"?

    du "klebst"(blittest) eine surface auf die andere um sie z.b. anzuzeigen. (sdl_blit() oder so ähnlich)



  • Oh, du hast recht... Es gibt ja tatsächlich eine Funktion SDL_blit() ^^

    Aber ich hab dafür einfach die Rect-Position mit der Mauscursorposition aktualisiert, sodass das Cursor-Rect nach dem Durchlaufen der Schleife eigentlich immer an der richtigen Stelle auftauchen sollte... Naja, es würd mir schon helfen, wenn ich den "eigentlichen" Mauscursor anzeigen lassen könnte - dann wüsst ich wenigstens, ob das Rect synchronisiert ist oder nicht.

    Wenn es hilft, hätte ich hier meinen Code für den Konstruktor der CMouse-Klasse sowie die Header-Datei - Verbesserungsvorschläge und Kritik sind erwünscht 😃

    //mouse.hpp
    #ifndef __CMOUSE__
    #define __CMOUSE__
    
    // Implementierung einer Mauscursoklasse
    //
    #include "constants.hpp"
    #include "sprite.hpp"
    
    class CMouse
    {
    	public:
    		CMouse();
    		~CMouse();
    
    		void Init();
    		void Quit();
    		void Render();
    		void Update(SDL_Event Event);
    		void Reset();
    
    		void setCursor() { SDL_SetCursor(m_pCursor); }				// Anzeigen des Cursors
    		void SetPos(Uint16 x, Uint16 y) { SDL_WarpMouse (x, y); }	// Position verändern
    		void show(int state) { SDL_ShowCursor(state); }				// Mauszeiger zeigen oder verstecken
    
    		SDL_Cursor *getCursor() { return m_pCursor; }
    
    	private:
    		CSprite		*m_pSpriteCursor;	// Sprite für den Cursor
    
    		SDL_Cursor	*m_pCursor;	// Zeiger auf den Cursor
    		Uint8		*m_pData;	// Daten des Cursors
    		Uint8		*m_pMask;	// Maske
    		int		m_width;	// Cursorbreite (vielfaches von 8!)
    		int		m_height;	// Cursorhöhe
    		int		m_hotx;		// "Hotspot"-Position x
    		int		m_hoty;		// "Hotspot"-Position y
    		float		m_fXpos;	// Xpos des Sprites
    		float		m_fYpos;	// Ypos des Sprites
    
    };
    
    #endif	//__CMOUSE__
    
    //mouse.cpp
    //Konstruktor
    CMouse::CMouse()
    {
    	// Initialisieren der Membervariablen
    	//
    
    	m_pSpriteCursor = NULL;
    	const unsigned short COUNT = 1;		// Benötigt für Data-Array (vielfaches von 8!)
    
    	m_pData = new Uint8[8*COUNT];
    
    	for(int i=0; i<(8*COUNT); i++)
    	{
    		m_pData[i] = 0;
    
    	}
    
    	// Maske
    	Uint8 Mask[] = 
    	{
    		255,	// 1 1 1 1 1 1 1 1	
    		113,	// 1 1 1 1 0 0 0 1	
    		113,	// 1 1 1 1 0 0 0 1	
    		113,	// 1 1 1 1 0 0 0 1	
    		129,	// 1 0 0 0 0 0 0 1	
    		129,	// 1 0 0 0 0 0 0 1
    		129,	// 1 0 0 0 0 0 0 1
    		255	// 1 1 1 1 1 1 1 1	
    
    	};
    
    	m_pMask = Mask;
    
    	m_width = 8*COUNT;
    	m_height = 8*COUNT;
    	m_hotx = 0;
    	m_hoty = 0;
    
    	// Mauszeiger erzeugen
    	m_pCursor = SDL_CreateCursor(m_pData, Mask, m_width, m_height, m_hotx, m_hoty);
    
    	// Mauszeiger mittig positionieren
    	//
    	Reset();
    
    	Uint16 xPos = static_cast<Uint16> (m_fXpos);
    	Uint16 yPos = static_cast<Uint16> (m_fYpos);
    
    	SetPos( xPos, yPos ); // Mauscursor positionieren
    


  • Hat keiner sonst einen Vorschlag, was da schief läuft? Hab ein wenig im Inet recherchiert, jedoch nichts gescheites finden können. -.-

    Btw fällt mir da noch etwas ein: Die .exe läuft ja nur, wenn die sdl.dll im selben Ordner liegt. Bei mir funktioniert das wunderbar, doch auf anderen Computern will sich das Prog nicht öffnen lassen... Muss ich zusätzlich die .lib-Dateien auch noch dazugeben? 😕



  • Jedoch findet da eine extreme Verzögerung statt und der Mauszeiger bewegt sich ziemlich schleppend über den Bildschirm

    wtf ist schleppend? sdl ist nicht unbedingt schnell. das ist alles was ich dir dazu sagen kann ohne dein quellcode zu studieren(wozu ich keine zeit habe) und dein system zu kennen.

    Ist mir schon zu Beginn aufgefallen, nämlich ist bei mir der Originalcursor nie sichtbar...

    schreib ein programm ohne schnickschnack um zu testen ob der mauszeiger tasächlich nie angezeigt und der fehler bei der sdl liegt. in dem falle wendest du dich besser an den hersteller.

    Die .exe läuft ja nur, wenn die sdl.dll im selben Ordner liegt. Bei mir funktioniert das wunderbar, doch auf anderen Computern will sich das Prog nicht öffnen lassen... Muss ich zusätzlich die .lib-Dateien auch noch dazugeben?

    nein eigentlich nicht. evtl verwenden er ein anderes os.
    im übrigen ist "will sich das Prog nicht öffnen lassen" eine scheiss fehlerbeschreibung.



  • krabbels schrieb:

    wtf ist schleppend?

    Schleppend ist langsam - im Vergleich zur Bewegungsgeschwindigkeit meiner Hand 🙄

    krabbels schrieb:

    schreib ein programm ohne schnickschnack um zu testen ob der mauszeiger tasächlich nie angezeigt und der fehler bei der sdl liegt.

    Jop, werd ich machen. 😉

    krabbels schrieb:

    nein eigentlich nicht. evtl verwenden er ein anderes os.
    im übrigen ist "will sich das Prog nicht öffnen lassen" eine scheiss fehlerbeschreibung.

    Die Fehlerbeschreibung ist in jedem Fall prägnanter als die Windows-Fehlermeldungen. 😛
    Die, denen ich das Prog geschickt hab, benutzen alle die selbe Version von WinXP Pro wie ich. Die Fehlermeldung war so in die Richtung "Anwendung nicht korrekt installiert"... Kann auch sein, dass ich irgendeine Einstellung bei den Projekteigenschaften vergessen hab - kenn mich mit dem ganzen Zeugs noch nit so wirklich aus -.-

    Edit: Hab jetz mal ein ganz einfaches Programm geschrieben, dass nur den Bildschirm und einen Cursor initialisiert. Ergebnis: Ich kann zwar per Event MOUSEMOTION die Mausdaten abfragen, auftauchen will der Cursor jedoch nicht. .



  • Btw fällt mir da noch etwas ein: Die .exe läuft ja nur, wenn die sdl.dll im selben Ordner liegt. Bei mir funktioniert das wunderbar, doch auf anderen Computern will sich das Prog nicht öffnen lassen... Muss ich zusätzlich die .lib-Dateien auch noch dazugeben? 😕

    vermutlich sind die ursachen eher falsche compiler-einstellungen als die sdl.

    Edit: Hab jetz mal ein ganz einfaches Programm geschrieben, dass nur den Bildschirm und einen Cursor initialisiert. Ergebnis: Ich kann zwar per Event MOUSEMOTION die Mausdaten abfragen, auftauchen will der Cursor jedoch nicht. .

    schau ob du die aktuelle version der sdl verwendest und poste deinen code mal.



  • Aaaah! xD
    Es stimmt - die SDL-Version war zu alt... Ich hatte noch v1.2.8 obwohl die Neuste v1.2.11 ist ~~

    Der Mauszeiger funktioniert jetzt - ich werd dann mal nachsehn, was beim anderen Programm schief geht. Ich vermute, du hast mit dem blitten Recht. Ich poste dann das Ergebnis 😉

    Danke schonmal für die Hilfe! 🙂

    Edit: Juhuu, es geht - hab glatt mal was richtig gemacht 😃
    Jetzt läuft endlich alles so, wie es soll. Nochmals vielen Dank!


Log in to reply