PowerVR Insider SDK

Ich habe noch eine bessere Möglichkeit gefunden, platformunabhängig Text darzustellen. Als erstes stieß ich durch Zufall auf heise.de auf NVIDIA Nsight Tegra, ein Plugin für Visual Studio, welches die native Entwicklung inclusive Debugging für Android auf komfortable Weise erlauben soll. Mir war das komplizierte Gefummel zuwieder, mit Eclipse Android NDK-Anwendungen zu debuggen. Leider funktioniert das Ganze bei mir nicht, aus der Traum. Das Installationsprogramm vermisste eine Benutzergruppe, die auf amerikanischen Windows-Systemen per default vorhanden ist. Die netten Entwickler haben also deutsche Benutzer vergessen. Nachdem ich diese Tatsache in einem Visual Studio-Protokoll herausgefunden und die Benutzergruppe meinem Rechner hinzugefügt hatte, wollte Visual Studio nicht starten. Das Plugin hatte etwas vermurkst. Die Support-Abteilung von NVIDIA war auch ganz freundlich, aber ein Update habe ich bis heute noch nicht gesehen. Dann muss ich also doch unter Windows mit einem Opengl ES-Emulator entwickeln und nach Android portieren.

Kürzlich habe ich aber einmal mehr gesucht und das PowerVR Insider SDK gefunden. Für die Platformen Windows, Linux, Android und iOS und noch mehr entwickelte Imagination Technologies mit diesem SDK ein Framework, welches die platformspezifischen Details heraus abstrahiert und ein grundlegendes API zur platformunabhängigen Grafikprogrammierung unter Opengl ES bereitstellt . Die Beispiele funktionieren tadellos und alles lässt sich anstandslos kompilieren (in meinem Fall mit dem Visual Studio für Windows und dem aktuellsten NDK für Android). Um Text zu dimensionieren, kann man die API fragen, welche Breite und welche Höhe ein Text einer bestimmten Größe im Bildschirmkoordinatensystem hat. Das ist genau, was ich gesucht habe, zumal dieses Framework auch Opengl ES 2.0 unterstützt. Aber insgesamt erkenne ich nun, dass diese grundlegenden Funktionen doch noch ein bisschen wenig ist, so dass man sehr viel selbst programmieren muss. Ich müsste z.B. erst einmal einen Textviewer programmieren. An Interaktionen ist auch nicht gedacht, sondern nur die grafische Darstellung. Vielleicht doch ein Spiele-Framework …

SGF-Player in Silverlight (Teil 2) – 99,1% Plattformunabhängigkeit

Nachdem ich die Machbarkeit eines Webservice erkundet habe, mache ich mich nun an die Implementierung eines Teils der Oberfläche und der Portierung der Logik von meiner letzten Entwicklung eines SGF-Players mit Java.
Als Erstes verpacke ich meine Oberfläche in ein Grid-Layout. Eine Zelle beherbergt eine ViewBox-Element. Wie in SVG werden Inhalte dieser Box skaliert, je nachdem, wieviel Platz sie innerhalb des Gitters im Browserfester zu Verfügung bekommt. Trotzdem kann die Box ein Rectangle in einem Canvas beinhalten, welches 1000 x 1000 Pixel groß ist. Auch wenn die tatsächliche Größe des Rechtecks abweicht, kann ich im Code mit dieser Größe rechnen. Auf diese Weise kann ich ganz einfach meinen Java Code portieren, der ebenfalls mit dieser Größe arbeitet.
Obwohl XAML keinen Standard für Vektorgrafik bietet, kann ich die Konzepte meiner Grafikgenerierung, die ich mit der SVG basierten Java-Bibliothek Batik entwickelt habe, übernehmen. Das Muster des Go-Bretts kommt durch eine große Textur zustande, ein Foto meiner Schreibtischplatte. Das bringt mir 500 KB Übertragungsoverhead ein. Aber in Zeiten der schnellen Leitungen kann ich eine Optimierung verzögern.
Die Portierung der Logik verlief am poblemlosesten. Ich kopierte meinen Java Code mit sehr wenigen Änderungen nach C#. Ich musste etwa die Syntax für mehrdimensionale Arrays oder von Stringoperationen ändern. Ein vollständiges Austauschen der for- in die besser lesbaren und eleganteren foreach-Anweisungen konnte ich mir nicht verkneifen.
Unter Windows flutscht die Anwendung. Rückmeldungen eines Mac-nutzenden Kumpels sind ebenfalls sehr positiv. Die Steine werden fast genauso schnell gesetzt, wie ich klicken kann. Als böse Überraschung finde ich unter Linux Unebenheiten vor. Auf meinem Rechner stellt Moonlight die Steine nicht korrekt dar. Auf dem Rechner meine Frau tut Moonlight es, dafür fehlen bei beiden Rechnern die Schatten. Installiere ich Moonlight 3, wird zwar alles korrekt dargestellt, aber die CPU-Auslastung ist sehr hoch, auch wenn die Anwendung ruhen sollte. Die Frickelei, um herauszufinden, woran es hapert, spare ich mir im Urlaub. Im Forum von go-mono.com habe ich mein Problem geschildert, wieder ohne Antwort. Das erfüllt mich nicht mit Vertrauen und ich hadere einen Moment.
Warum andererseits trauern? Meine Zielgruppe sind Clientnutzer und die benutzen zu 99,1 % Windows oder Macintosh. Es gibt laut Net Market Share nur 0,9% Linuxinstallationen auf dem Desktop. Und hier geht es ja nicht um Jesus, der seine 99 Schafe zurücklässt, um ein verlorenes Schaf zu retten. Und vielleicht macht sich Moonlight ja noch. Und wer interessiert sich schon für Go?
Hier die Anwendung. Die inhaltliche Benutzbarkeit muss natürlich erst noch hergestellt werden.

SGF-Player in Silverlight (Teil 1) – Visual Studio statt MonoDevelop

Ich mag Silverlight. Es wurde tatsächlich von Microsoft mit dem Anspruch entwickelt, plattformunabhängig zu sein. Da Microsoft der .NET-Nachbildung Mono seit den Anfängen von Mono bisher keinerlei Beschränkungen auferlegt hat, ist auch später nicht mit Patentklagen zu rechnen.
Als Demoanwendung will ich wieder einen SGF-Player entwickeln, diesmal fürs Web. Da Unmassen von Go-Spielen nicht bei jedem Aufruf des Players auf den Client geladen werden können, komme ich um einen Webservice nicht herum. Denn Silverlight ist eine Clienttechnologie und kann keine direkte Datenbankverbindung aufbauen.
Ich würde gerne in Silverlight mit meinem privaten Lieblingsbetriebssystem, Linux, entwickeln. Daher probiere ich mit MonoDevelop, einen Webservice zu programmieren. Auf www.webservicex.net finde ich einen Service, der das Symbol eines Unternehmens entgegen nimmt und mir die Aktienwerte zurück gibt.
Informationen, wie ich einen Webservice mit unter Mono entwickele sind spärlich aber ich finde ein repräsentatives Beispiel von Mono selbst. Lege ich mit MonoDevelop ein Moonlight-Projekt an und füge ich eine Webreferenz auf die Adresse des Service hinzu, wird zwar die WSDL (Web Service Description Language)-Datei des Service gefunden und es werden Servicezugriffsklassen generiert. Aber, oh Schande: der generierte Code lässt sich nicht übersetzen. Der Namespace der Zugriffsschicht ist ein ‘.’ und der Code benutzt den Namespace System.Web.Service, welcher in Silverlight nicht existiert. Auf meine Schilderung meines Problems im Forum von www.go-mono.com bekomme ich keine Antwort.
Danke, das wars dann. Ich versuche mein Glück mit dem Visual Studio unter Windows. Es gibt Beispiele wie Sand am Meer und ich kann meinen Service problemlos entwickeln.
Folgenden Codeschnipsel habe ich geschrieben, nachdem ich eine Servicereferenz auf den Webservice gesetzt habe und die Zugriffsklassen fehlerfrei generiert wurden.

Hier der C#-Code:

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            ServiceReference1.StockQuoteSoapClient proxy = new ServiceReference1.StockQuoteSoapClient();
            //Wire the proxy to a completed handler to allow the async operation to be handled
            proxy.GetQuoteCompleted +=
              new EventHandler<ServiceReference1.GetQuoteCompletedEventArgs>(
            proxy_GetCustomerCompleted);
            //Call the service asynchronously
            proxy.GetQuoteAsync("GOOG");
        }

        void proxy_GetCustomerCompleted(object sender, ServiceReference1.GetQuoteCompletedEventArgs e)
        {
            //Bind the returned data to the DataContext
            System.Windows.Browser.HtmlPage.Window.Alert(e.Result.ToString());
        }
    }
}

Die Antwort des Webdienstes auf “GOOG” ist nachfolgend in XML abgebildet.
webServiceAntwort

Eine Silverlight-Anwendung wird publiziert, indem einfach die HTML- und die dazu gehörige XAP-Datei auf den Server kopiert werden. Das Schöne: Die Anwendung ist tatsächlich plattformunabhängig. Unter Linux funktioniert die Anwendung genauso wie unter Windows. Unter Linux zwar mit einer Meldung, dass es sich um eine Silverlight 3-Anwendung handelt, Moonlight jedoch erst Silverlight 2 abdeckt. Es sei also mit Imkompatibilitäten zu rechnen. Das stört mich allerdings weniger, da die nächste Moonlight Version Silverlight 3 abdecken und im 1. Quartal 2011 heraus kommen soll.
In einer Antwort in einem Forum auf www.go-mono.com habe ich gelesen, dass sich das Mono-Team bisher hauptsächlich auf die Lauffähigkeit von Mono-Anwendungen konzentriert hat statt auf das Bereitstellen einer funktionstüchtigen IDE. Die Erfahrung habe ich hiermit auch gemacht.

SGF Player mit Java und Batik – 2

Schönheit First

Mich interessiert zuerst, wie ich in SVG ein äußerlich passables Go-Brett mit Steinen hinbekomme. Im Netz finde ich ein mit Inkscape erzeugtes welches. Der SVG-Code ist gruselig: Die Koordinaten für die Gitterpunkte des Brettes haben etliche Nachkommastellen und die Datei enthält viel zu viele Knoten, welche ich nicht verstehe und nicht brauche. Unverständlicher, generierter Code, den ich nicht programmatisch manipulieren möchte, da ich an die Koordinaten und Knoten schlecht heran komme. Also schreibe ich mir meinen SVG-Code anhand von W3C-Spezifikation und Beispielen selber. Als erstes erzeuge ich mir mit dem SVG-Attribut ViewBox ein eigenes Koordinatensystem. Dieses Koordinatensystem lässt sich als Auflösung auffassen. Ich sage damit, wie groß meine Auflösung immer ist, egal, wieviel Platz ich tatsächlich zur Verfügung habe. Das macht mein SVG-Dokument skalierbar.
Für das Holzbrett zeichne ich nun ein Rechteck in hellbraun. Da ich unbedingt eine Art Holzmaserung sehen will und andernfalls nicht auf das Brett gucken kann, definiere ich mir für das Rechteck einen Filter, der aus den Effekten feTurbulence und feDiffuseLighting besteht.
Das Gitter zu zeichen ist trivial, doch das mache ich lieber in Java mit einer for-Schleife, da ich dann alle Abstände zentral ändern kann, statt 19 mal 19 Linien händisch zu programmieren. Um die Steine zu zeichnen definiere ich mir für schwarze und weiße Steine jeweils einen radialGradient-Knoten und einen Filter für den Schatten. Nachdem ich probeweise einige Steine gezeichnet habe, sehen diese zwar ganz reizend aus, aber wenn der Schatten zu groß ist, fällt er über den benachbarten Stein. Ich finde auf Anhieb keine Lösung, bin aber damit zufrieden, wenn der Schatten nur 1 Pixel breit ist und dieser bei einem Abstand eines Steines vom nächsten von ebenfalls 1 Pixel nur noch aufs Brett fällt.
Nun fange ich an, für ein Spiel Stein für Stein aufs Brett zu zeichnen, indem ich die ‘Logik’ ausblende. Die Logik besteht daraus, dass auch Steine vom Brett genommen werden müssen, wenn ein gesetzter Stein eine Gruppe gegnerischer Farbe berührt und dieser die letzte Freiheit nimmt. Ich möchte am liebsten pro Zug alles neu darstellen und alle Steinknoten dem SVG Dokument neu hinzufügen. Doch je mehr Steine ich hinzufüge, desto länger dauert es. Da die Verzögerung deutlich erkennbar ist, brauche ich eine Lösung. Im Netz kursiert der Vorschlag, vom SVG-Dokument ein Fragment abzuspalten und alles nötige zuerst dem Fragment anzuhängen, bevor das Fragment als Ganzes in das Dokument eingefügt wird. So müsse die Darstellung des Dokuments nur einmal gerechnet werden. Leider schafft auch dieser Vorschlag keine wesentliche Abhilfe. Deshalb gebe ich jedem Steinknoten eine eindeutige ID und füge nur einen neuen Knoten hinzu, wenn es ihn noch nicht gibt.

Logik

Da die Darstellung der kleinen Anwendung nun flüssig läuft und schön aussieht, kann ich mich nun der Logik zuwenden. Ein Zug verändert den Zustand des Brettes. Ein Zustand ist vom vorherigen Zustand abhängig. Wie kann ich es erreichen, dass ich wahllos zu irgendeinem Brettzustand eines Spiels springen kann, z.B. Zug n? Ich muss für Zug n den Zustand aus den voran gegangenen n-1 Zuständen errechnen. Meine eigenen Gedanken zum Thema Freiheiten von Steinen berechnen und diese Steine nahtlos vom Brett entfernen, erscheinen mir sehr kompliziert und ich schaue mir den offenen Quellcode von qgo an. Dieser Code ist in C++ geschrieben und ich finde sofort, was ich brauche. In dem qgo-Modell existieren Gruppen von Steinen. Beim Setzen eines Steins wird geprüft, ob er einer Gruppe angehört. Dabei wird Stein für Stein geschaut, ob der neue Stein von der Position her ein nördlicher, südlicher, westlicher oder östlicher Nachbar sein könnte. Gehört er zwei Gruppen an, werden die zwei Gruppen zu einer Gruppe verbunden und der Stein hinzugefügt. Gehört er keiner Gruppe an, wird aus ihm eine neue gebildet. Weiter wird pro Zug der Stand der Freiheiten der Gruppen anhand des Brettzustands berechnet. Hat mindestens ein Stein einer Gruppe einen benachbarten Punkt, der weder von einem weißen noch einem schwarzen Stein besetzt ist, besitzt die Gruppe Freiheit. Hat die Gruppe keine mehr, wird sie gelöscht, nachdem Stein für Stein dieser Gruppe vom Brett genommen wird. Es wird also pro Zug allerhand berechnet, aber das geht immer noch schneller, als ich klicken kann.
Zum Schluß hätte ich gerne noch alle 40.000 Spiele, die ich in einer viele MB großen Datei beherberge, in einer übersichtlichen Tabelle. Dort möchte ich Spiele anhand von Spielernamen, Turnier und Datum filtern können. Dies habe ich mir schon einmal mit F# in .NET programmiert. Aber wie ich festellen muss, sind es in Java mehr Zeilen und geht nicht so leicht von der Hand. Die string.split() Funktion in Java ist nämlich viel zu langsam, da sie einen regulären Ausdruck als Argument erwartet. Zum parsen des Strings, der alle Spiele enthält, muss ich ihn char für char begutachten, mir Positionen von Spieltrennern merken und pro Spiel einen Substring aus dem Gesamtstring extrahieren. Auch das läuft nach einigen Optimierungen flüssig, so dass der Import nur ein paar Sekunden dauert.

So sieht der Player aus:
SGF_Player_Batik_Swing

Sogar mein 4-jähriger Sohn kann auf diese Weise Profi-Partien nachspielen! Züge können in der geschwindigkeitsverstellbaren Animation äußerst gut gefunden werden, statt in einem PDF-Dokument, welches 50 Züge als Zahlen beinhaltet, suchen zu müssen.

SGF Player mit Java und Batik – 1

Ich schaute mir ja so gerne Amatuerpartien von hochrangigen Go-Spielern auf dem KGS-Server an. Doch jetzt schaue ich mir, seit dem ich mir einen SGF Player entwickelt habe, lieber Profi-Partien an. Als ich mit einem Kollegen über mein Vorhaben sprach, war sein erster Rat: SVG. Dieses Format findet demnächst seinen Weg in den Internet Explorer 9 und in den Firefox ist es jetzt schon integriert. Erste Erkundungen waren beeindruckend. SVG öffnet einen Weg, Spiele in den Browser zu bringen, indem SVG-Inhalte, die sich im DOM befinden, über Javasript manipuliert werden können. Doch wie viele Enwtickler machte ich um Javascript bisher einen weiten Bogen. Lange gab es für die Entwicklung mit Javascript keine IDE, was sich jetzt eigentlich geändert haben dürfte. Aber eine neue Technologie, nämlich SVG, ist mir erst einmal genug. Ich will Schritt für Schritt vorgehen und nur eine neue Sache auf einmal lernen. Und schließlich muss es nicht direkt ins Web. Mein Blick fällt auf die Bibliothek Batik, welche die Manipulation von SVG mittels der mir vertrauten Sprache Java ermöglicht. Das Beispiel sieht denn auch sehr vielversprechend aus: Es ist sogar möglich, ein Applet zu entwickeln, welches sehr wohl übers Web ausgeführt werden kann.
Als nächstes entscheide ich mich für die NetBeans IDE und binde die Batik-Archive in mein Projekt ein. NetBeans behagt mir auf Anhieb. Die Bedienung ist sehr ähnlich zum Visual Studio. Im Gegensatz zur C++-Unterstützung von Visual Studio kann ich hier jedoch sehr bequem Klassen oder das Projekt umbennennen, Code refaktorisieren und fehlende Importe einfügen. Da ich jetzt doch wieder einen Haufen neuer Technologien auf einmal vorfinde, will ich zunächst die Batik Beispielanwendung in eine Swing-Anwendung überführen.
Das Ergebnis:

Batik-Beispiel in Java Swing - klein

Batik-Beispiel in Java Swing - klein


Batik-Beispiel in Java Swing - groß

Batik-Beispiel in Java Swing - groß

Das Ergebnis stellt mich sehr zufrieden und entspannt lehne ich mich zurück. Mit Java unter Linux bin ich zufrieden. Swing schnurrt schnell und Anwendung und IDE, die ebenfalls in Java programmiert ist, laufen flüssig. Das SVG-Dokument ist interaktiv über Java manipulierbar und die Manipulation verläuft ohne Flackern. Das Ergebnis ist frei skalierbar, ohne, dass ich hierfür Aufwand betreiben müsste. Die Technologien sind gefunden, um meinen ersten SGF-Player zu verwirklichen.