siredmar / mdcii-engine

Platform independent remake of the game Anno 1602/1602AD.
GNU General Public License v2.0
19 stars 3 forks source link

History Edition - BSH Files #87

Open stwe opened 3 years ago

stwe commented 3 years ago

Wie in einem Issue bereits ausgeführt, sind die neuen BSH Files nicht kompatibel mit der mdcii-engine. Ich mache hier mal ein Ticket auf, verbunden mit dem Anspruch, das Problem zu lösen. In meiner eigenen Renderengine fehlen mir ebenfalls Bilder aus der Stadtfld.bsh. Am Anfang der BSH Datei stehen die Offsets zu den eigentlichen Bildern. Wenn man jetzt über alle Offsets iteriert, kann man die Breite, die Höhe, den Typ und die Länge der darauf folgenden Pixeldaten auslesen. In der History Ed. komme ich so auf insgesamt 5964 Bilder, die gespeichert irgendwann so aussehen:

Trash

Um die vielen schwarzen Bilder, die ab Bildnummer 1840 (Zählung ab 0) beginnen, habe ich erstmal folgendes gemacht. In einem ersten Schritt habe ich mir den Offset des ersten "Schrottbildes" ausgeben lassen. Das ist Dezimal (1967656 + 20).

Der Hexeditor gibt mir an dieser Stelle folgendes:

Schrott

Das blau markierte ist das ganze Bild! Die Werte sagen: 64 breit, 31 hoch, Typ 1 mit einem Pixelblock von angeblichen 20 Byte. Darauf folgt: FF FE FE FE. Das wars. Klar, das das Schwarz ergibt. Danach geht es mit einem ganz normalen Bild weiter. Nun habe ich gedacht, dass ich diese "Schrott-Sequenz" mehrfach in der Datei finde und habe mir den Offset des nächsten "Schrottbildes" ausgeben lassen. Weit gefehlt: Es ist der gleiche Offset. Insgesamt wird auf diesen Block 1400 mal verwiesen, was die enorme Anzahl an fehlenden Bildern erklärt. Überhaupt sind viele Offsets mehrfach vorhanden - allerdings mit Bilddaten.

Die Frage ist nun, wo sind die Bilddaten hin. Vielleicht handelt es sich auch nur um einen DummyBlock. Vielleicht hat da jemand eine Idee.

siredmar commented 3 years ago

Diese Schrottbilder interpretiere ich als Platzhalter, damit die Indizes stimmen fuer die Darstellung von Objekten groesse als 1x1; sozusagen als Platzhalter. Diese 0xFE stellt einen 'End Marker' da und das 0xFF das Zeilenende. Schau dir mal die Bilddaten zum Schloss an (ID sollte sich aus der haeuser.cod -> json) gut rausfinden lassen. Wenn ich mich richtig erinnere, sind da einige Platzhalter drin.

Green-Sky commented 3 years ago

Weit gefehlt: Es ist der gleiche Offset. Insgesamt wird auf diesen Block 1400 mal verwiesen,

Es handelt sich hier um eine einfache Form von "Kompression", in dem doppelte bilder vermieden werden.

stwe commented 3 years ago

Ok das mit den Schloss Ids werde ich mir ansehen. Danke für den Tip.

Zum Thema Indizes: Bei sehen fehlende Bilder so aus. Man achte auf den Markt mit der Id 809:

Fehler

Da fehlen 3(?) Bilder. Der Startindex ist 4700 und wird richtig ausgelesen. Nun folgt folgende Funktion:

        var index = building.gfx;

        var directions = 1;
        if (building.rotate > 0) {
            directions = 4;
        }

        var aniSteps = 1;
        if (building.animAnz > 0) {
            aniSteps = building.animAnz;
        }

        index += building.rotate * (tile.orientation % directions);

        switch (tile.orientation) {
            case 0: index += tile.yPosOnIsland * building.width + tile.xPosOnIsland;
                break;
            case 1: index += (building.height - tile.xPosOnIsland - 1) * building.width + tile.yPosOnIsland;
                break;
            case 2: index += (building.height - tile.yPosOnIsland - 1) * building.width + (building.width - tile.xPosOnIsland - 1);
                break;
            case 3: index += tile.xPosOnIsland * building.width + (building.width - tile.yPosOnIsland - 1);
                break;
            default: LOGGER.warn("Unknow rotation.");
        }

        index += building.width * building.height * directions * (tile.animationCount % aniSteps);

Das Ergebnis sieht so aus:

Index Markt: 4720 trash pic Index Markt: 4716 trash pic Index Markt: 4712 Ecke Index Markt: 4721 trash pic Index Markt: 4717 trash pic Index Markt: 4713 vorne Index Markt: 4722 trash pic Index Markt: 4718 trash pic Index Markt: 4714 Markt mit Teil vom Wagen

siredmar commented 3 years ago

Die Gebaeude um den Markt herum (ausser das von den Pionieren) kenne ich gar nicht. Sind das welche die aus der neuen History Edition kommen oder ist das noch ein Fehler mit, im Originalspiel, ungenutzten Grafiken?

stwe commented 3 years ago

Ich arbeite komplett mit der History Edition. Eine andere Version habe ich gar nicht (mehr). Hier mal ein Screenshot der gleichen Szene direkt aus dem Spiel heraus.

Unbenannt

stwe commented 3 years ago

Also Stand jetzt: mein Programm rendert Savegames in allen drei Zoomstufen ohne Problem mit einer FPS von ca 1600.

Ick freu mir.

Dabei stellt die Zoomstufe keine große Rolle. Das meiste wird der GPU vorgefertigt übergeben. Ich muss allerdings sagen, dass es bei umfangreicherer Bebauung der Inseln zu Problemen kommen kann, da ich momentan nur ein Texturarray benutze und wenn die Inseln mehr und mehr bebaut sind, kommt man damit nicht mehr hin. Was die BSH Dateien angeht, so kann man die uneingeschränkt benutzen. Jedenfalls sehe ich momentan keine Problem mehr. Die sog. "Schrottbilder" sind ein Feature. Danke an alle für die Hinweise und die Hilfe.

Result

stwe commented 3 years ago

Mal ein Update zu dem Unterschied zwischen den BSH Files der NINA und History Ed.

Beim Einlesen der Stadtfld.bsh hatte ich keinerlei Unterschied festellen können. Nun beschäftige ich mich mit dem Menü und habe dafür versucht, die Start.bsh zu laden. Und siehe da, die Programmierer haben offenbar für die neue Version etwas geändert.

  1. Es sind in der NINA 90 Bilder enthalten und in der Hist Ed. zwei mehr - also 92.
  2. Das erste Bild in der Hist Ed. findet sich demnach auch bei Offset 368 statt 360.
  3. Der Typ und die Größe einiger Bilder hat sich geändert.

Beispiel erstes Bild in der Hist. Ed.

        /*
        History
        [....BshFile] DEBUG - offset: 368
        [....BshFile] DEBUG - width: 1024
        [....BshFile] DEBUG - height: 768
        [....BshFile] DEBUG - type: 13
        [....BshFile] DEBUG - length: 3179536
        */

        /*
        Nina
        [....BshFile] DEBUG - offset: 360
        [....BshFile] DEBUG - width: 1024
        [....BshFile] DEBUG - height: 768
        [....BshFile] DEBUG - type: 1
        [....BshFile] DEBUG - length: 794896
        */

Für den Typ 13 wurden statt Bytes einfach 4 Byte große Ints gespeichert. Statt Palettenindex sind die Farbwerte direkt hinterlegt. Die Funktion zum Einlesen habe entsprechend angepasst.

    private void decodeTexture13(TextureHeader textureHeader) throws IOException {
        int x = 0;
        int y = 0;

        while (true) {
            int numAlpha = chunk0.getData().getInt();

            if (numAlpha == END_MARKER) {
                break;
            }

            if (numAlpha == END_OF_ROW) {
                x = 0;
                y++;
                continue;
            }

            for (int i = 0; i < numAlpha; i++) {
                textureHeader.image.setRGB(x, y, 0);
                x++;
            }

            int numPixels = chunk0.getData().getInt();
            for (int i = 0; i < numPixels; i++) {
                var b = chunk0.getData().get();
                var g = chunk0.getData().get();
                var r = chunk0.getData().get();
                var a = chunk0.getData().get();

                var color = Util.rgbToInt(Util.byteToInt(r), Util.byteToInt(g), Util.byteToInt(b));

                textureHeader.image.setRGB(x, y, color);
                x++;
            }
        }

        if (SAVE_AS_PNG) {
            saveAsPng(textureHeader.image, textureHeader.offset);
        }

        var bshTexture = new BshTexture(textureHeader.image);
        bshTextures.add(bshTexture);
    }
siredmar commented 3 years ago

Super! Das liegt daran, dass die HE beim Startbildschirm neue Grafiken eingebaut hat. Offenbar war den neuen Entwicklern es zu stressig die Bilder mit der vorhandenen Farbpalette zu machen. Stattdessen haben sie sich gedacht, wir erfinden einfach nen neuen Typ und lesen den anders ein.

Super rausgefunden!