Intern/Developer Resources

From BlinkenSisters

Auf dieser Seite gibts eine Zusammenfassung wichtiger Themen und Links aus der Team-Mailingliste.

Contents

C-Spezifisches

Datentypen und Alignment

> btw: Uint32 ist richtig für currentBLPFrame.pixels[i] ??

Nicht, wenn du die Struktur direkt übers Netz schieben willst. Vergleichen wir mal (benötig fixed-width-fonts, z.B. Courier)

.--------------------------------------.
|              Datentypen              |
+-------------+-------+-------+--------+
| Eigenschaft | char  | Uint8 | Uint32 |
+-------------+-------+-------+--------+
| Bytes       | 1     | 1     | 4      |
| Aligned     | nein  | ja    | ja     |
| Padding     | nein  | ja    | ja     |
| Byte-Order  | keine | keine | Host   |
'-------------+-------+-------+--------'

Ok, Uint32 hat mal die falsche Zahl von Bytes. Aber man könnte theoretisch ja Uint8 verwenden, oder? Falsch, alle numerischen Basisvariablen können von Hardware und/oder Betriebssystem sogenanntes Alignment verlagen (z.h. ein Uint* muss z.B. an einer 8-Byte-Grenze liegen, damit der Prozessor das verwenden kann.) Dazu wird per "Padding" die Datenstruktur entsprechend "vergrößert" und Bytes leergelassen.

Zusätzlich liegen numerische Werte immer in Host-Byte Order vor (Big- oder Little-Endian; es gibt sogar Mischformen). Du brauchst BLP-Pakete aber immer in Network-Byte-Order.

"char" ist also IMHO die richtige Wahl. Du kannst natürlich auch was anderes verwenden, musst das Paket dann aber "händisch" erstellen. Beispiele dafür gibts in den BMF-Handlern, dort muss ich auch Plattform-Übergreifend arbeiten. Für das senden der Pakete würd ichs halt gleich in der richtigen Form generieren; spart Rechenzeit.

Hier ein paar Links zum Thema:

http://en.wikipedia.org/wiki/Endianness

http://en.wikipedia.org/wiki/Data_structure_alignment


Betriebssystem-Unabhängigkeit

BlinkenSisters soll unabhängig vom installierten Betriebssystem und von den Hardware-Details sein. Leider konnten deshalb manche verfügbare Lösungen nicht verwendet werden oder mussten komplett am BS angepasst werden:


BlinkenLIB

>> Also, sofern wir das verwenden (muss zuerst noch MacOSX und Windows
>> testen!), wird die lib direkt in unseren Source-Stand übernommen und direkt
>> einkompiliert. Als extra Library ist das ungünstig, weils die BlinkenLIB
>> auf den meisten Betriebssystemen so nicht gibt.
>> Wenn sich herausstellt, daß die lib Betriebssystemabhängig ist, kommt die
>> nicht ins Projekt rein...
>Grad gesehen, daß die lib direkte Systemcalls macht (winsock und so). Die
>BlinkenLIB ist damit in dieser Form für BS gestorben!
Das klingt plausibel.
Ich dachte auch schon daran, die Lib für bs anzupassen.
Also den Netzwerk- Seriell ... kram raus und ggf. an sdl anpassen. 
Oder einfach teilweise raushohlen, was man so braucht;-)

Leider hat sich die BlinkenLIB, wie so manches andere, als zu Betriebssystem-abhängig herausgestellt. Da das Spiel aber aud jeder Plattform, auf der SDL verfügbar ist, laufen soll, kann auch die BlinkenLIB nicht verwendet werden.


SDL Probleme

Bekannte SDL-Probleme und Workarounds.


SDL_TTF / Font Rendering

jetzt kann ich BS installieren.

Nur wenn ichs starte kommt:
Broken SDL_TTF / TTF_RenderText_Solid() has indicated an error ()!
Broken SDL_TTF / TTF_RenderText_Solid() has indicated an error ()!
Broken SDL_TTF / TTF_RenderText_Solid() has indicated an error ()!
Broken SDL_TTF / TTF_RenderText_Solid() has indicated an error ()!
...

Dieses Problem ist im aktuellen Source behoben. TTF_RenderText_Solid() aus der SDL_TTF funktioniert auf vielen System nicht oder nicht zuverlässig. Das ist ein bekanntes Problem, gegen das wir (besonders Dauti! Danke!) folgend vorgegangen sind:

  • Statt TTF_RenderText_Solid() wird jetzt TTF_RenderText_Blended() verwendet. Schaut besser aus und es gibt keine "known bugs", die sich auf BlinkenSisters auswirken
  • Zusätzlich gibts eine Fallback-Option, die automatisch anspricht, falls das TTF-Rendern fehlschlägt
  • IM Fallback wird showText() aufgerufen, das einen vorgerendertern Bitmap-Font verwendet. Schaut im Menü nicht so schön aus, funktioniert aber immer.


Sound-Probleme

Bei mir knackt der Sound seit einiger Zeit ziemlich heftig. Ich glaube 
seit dem upd8 bzgl sound-engine. weiß ich aber nicht so genau. ich benutze 
oft "-s"...

Weitere Probleme mit dem Sound sind uns bekannt. Dieses Problem scheint unabhängig von der Größe des Audiobuffers; ein mögliches Problem liegt an der Hardware-Seite durch Störungen und/oder die Systemauslastung.

An einer Lösung bzw. Ausforschung der Problemursache wird gearbeitet. Dies ist leider nur direkt an der betroffenen Hardware möglich und schwer nachvollziehbar.


Keymaps / Tastenbelegungen

> Hab mir jetzt einen gestern gemeldeten Bug mit dem Turbo-Mode angeschaut:
>
> Offensichtlich werden verschiedene Tasten auf div. Betriebssystemen "falsch"
> zurückgemeldet. Ich hab mal einen temporären Fix für Windoofs eingebaut.
> 
> Ich schau mir das genauer an. Warscheinlich muss ich das ganze
> Konfigurierbar machen...


Laut SDL-Doku auf http://www.libsdl.org/cgi/docwiki.cgi/SDLKey werden auch Tasten, die eigentlich auf allen Keyboards vorhanden sind, nicht immer mit den "richtigen" SDL-Keyboard-Codes (Keysyms) zurückgemeldet. Das hängt von Tastaturlayout und Betriebssystem ab. An einer - durch den Benutzer - konfigurierbaren Lösung wird gearbeitet.


Multitasking / MultiThreading / Zeitsteuerung

> msleep( MILLISECONDS );  // <-- Wie kann
> man  das mit sdl beschreiben?

Ein sleep geht so:

SDL_Delay(MILLISECONDS);

Aber das ist meistens GANZ schlecht. Das SEND sollte zyklich aufgerufen werden, nachsehen ob die Haltezeit für den Frame um ist, ggf senden, und sofort wieder aus der Funktion rausgehen.

Die alternative ist, dich mit den Multithreading-Geschichten von SDL zu befassen, Funktionen zu bauen, in denen ich abspielen aus der Engine cross-thread starten/stoppen kann und am besten gleich mal in "Design and Implementation of Operating Systems" von Tannenbaum die Kapitel über Multitasking/Multithreadind durchzulesen. Mag man nicht machen, wenns anders geht. Ausserdem wär die Literatur von Edsger Dijkstra zum "Dining philosophers problem" wichtig. Siehe auch http://en.wikipedia.org/wiki/Dining_philosophers_problem und http://en.wikipedia.org/wiki/Multi-threading und http://en.wikipedia.org/wiki/Computer_multitasking. Auch die verlinkten Seiten sind wichtig.

Kannst frei wählen. Aber zur Info: Multi-Tasking Geschichten sind ausserdem extrem blöd zum debuggen, ich persönlich vermeids und schreib mir - so wie in anderen Teilen von BS auch gemacht wird - eine simple Version von "Cooperative Multitasking": Jeder Programmteil hat seine eigenen Daten, läuft zyklisch von der aufrufenden Engine angestossen und gibt die Programmausführung per "return;" so schnell wie möglich wieder an den Aufrufer ab - es sein denn, es SOLL ein blockierender Aufruf sein, wie z.B. eine "Yes/No"-Abfrage.

Eine korrekte Implementation für z.B. Senden verschieden lang dauernder Frames wäre folgendes:

Global im File:

Uint32 frameTicks;

Init-Funktion:

initSendFrame() {
    frameTicks = 0;
}

De-Init-Funktion (wird nicht gebraucht, sollte der Form halber aver implementiert werden):

deInitFrame() {
    // Nothing to do
}

Und dann die eigentliche Send-Funktion, die zyklisch aufgerufen wird:

sendFrame() {
    Uint32 curTick = SDL_GetTicks();
    if(frameTicks == 0) {
        // Need to send a frame, nothing to do
    } else if(frameTicks > curTick) {
        // Current frame still active
        return;
    }
    // main timing loop
    MYFRAME frame;
    while(frameTicks < curTick) {
        // loop until we reach "present" to skip frames in case
        // we where delayed elsewhere
        frame = getNextFrame();
        frameTicks += frame.delayTime;
    }
    // Send the frame
}

So funktionierts dann auch, wenn durch irgendeinen Grund die Framerate nicht gehalten werden kann, z.B. weil der Rechner ausgelastet ist/war.