Zum Inhalt springen

Codeschnippel von C++ nach Java - Frage


Devilmarkus

Empfohlene Beiträge

Hallo zusammen,

ich versuche, aus einem alten DOS Spiel die Grafiken zu lesen.
Das klappt soweit auch schon sehr gut, aber es gibt in dem Spiel auch komprimierte Grafiken.
Nun war ich nicht ganz Faul, und habe mir den Source für die ScummVM angeschaut.
Die kann das Spiel auch darstellen.

Dort bin ich auch auf die Dekomprimierungsroutine gestoßen:

	byte *AGOSEngine::vc10_uncompressFlip(const byte *src, uint16 w, uint16 h) {
	    w *= 8;
	    byte *dst, *dstPtr, *srcPtr;
	    byte color;
	    int8 cur = -0x80;
	    uint i, w_cur = w;
	    dstPtr = _videoBuf1 + w;
	    do {
	        dst = dstPtr;
	        uint h_cur = h;
	        if (cur == -0x80)
	            cur = *src++;
	        for (;;) {
	            if (cur >= 0) {
	                /* rle_same */
	                color = *src++;
	                do {
	                    *dst = color;
	                    dst += w;
	                    if (!--h_cur) {
	                        if (--cur < 0)
	                            cur = -0x80;
	                        else
	                            src--;
	                        goto next_line;
	                    }
	                } while (--cur >= 0);
	            } else {
	                /* rle_diff */
	                do {
	                    *dst = *src++;
	                    dst += w;
	                    if (!--h_cur) {
	                        if (++cur == 0)
	                            cur = -0x80;
	                        goto next_line;
	                    }
	                } while (++cur != 0);
	            }
	            cur = *src++;
	        }
	    next_line:
	        dstPtr++;
	    } while (--w_cur);
	    srcPtr = dstPtr = _videoBuf1 + w;
	    do {
	        dst = dstPtr;
	        for (i = 0; i != w; ++i) {
	            byte b = srcPtr[i];
	            b = (b >> 4) | (b << 4);
	            *--dst = b;
	        }
	        srcPtr += w;
	        dstPtr += w;
	    } while (--h);
	    return _videoBuf1;
	}



Das byte[]_videoBuf1 ist 32000 Bytes gross. (160x200 Pixel)

Nun habe ich versucht, diese Routine in Java umzuwandeln, aber stoße absolut an meine Grenzen für das Verständnis von C++:

	
	    byte[] vc10_uncompressFlip(byte[] src, int w, int h) {
	        w *= 8;
	        int dst;
	        int soff = 0;
	        int dstPtr;
	        int srcPtr;
	        byte color;
	        int cur = -0x80;
	        int i, w_cur = w;
	        dstPtr = w; //we really write to videoMemory
	        boolean break1 = false;
	        soff = 0;
	        nextline:
	        do {
	            dst = dstPtr;
	            int h_cur = h;
	            if (cur == -0x80) {
	                cur = src[soff++];
	            }
	            for (;;) {
	                if (cur >= 0) {
	                    /* rle_same */
	                    color = src[soff++];
	                    do {
	                        _videoBuf1[dst] = color;
	                        dst += w;
	                        if (--h_cur != 0) {
	                            if (--cur < 0) {
	                                cur = -0x80;
	                            } else {
	                                soff--;
	                            }
	                            break1 = true;
	                            break;
	                        }
	                    } while (--cur >= 0);
	                } else {
	                    /* rle_diff */
	                    do {
	                        _videoBuf1[dst] = src[soff++];
	                        dst += w;
	                        if (--h_cur != 0) {
	                            if (++cur == 0) {
	                                cur = -0x80;
	                            }
	                            break1 = true;
	                            break;
	                        }
	                    } while (++cur != 0);
	                }
	                if (break1) {
	                    break1 = false;
	                    break;
	                }
	                cur = src[soff++];
	            }
	            dstPtr++;
	        } while (--w_cur != 0);
	        dstPtr = w;
	        srcPtr = dstPtr;
	        do {
	            dst = dstPtr;
	            for (i = 0; i != w; ++i) {
	                int b = _videoBuf1[i + srcPtr] & 0x0ff;
	                b = (b >> 4) | (b << 4);
	                _videoBuf1[--dst] = (byte) b;
	            }
	            srcPtr += w;
	            dstPtr += w;
	        } while (--h >= 0);
	        return _videoBuf1;
	    }



Wer kann mir hier weiter helfen?
Ich verstehe weder die DO-Schleifen wirklich, noch, wie ich ein "Replacement" für das "goto" schaffen kann.
Wer traut sich zu, den obigen Code möglichst 1:1 bzw, so, dass ich es verstehe, in einen Pseudo-Code zu wandeln?

LG
Markus

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok, habs herausgefunden (Zumindest so, dass es für meine Bedürfnisse funktioniert)
 

	
	    public byte[] readCompressed(byte[] srcData, int offset, int w, int h) {
	        w /= 2;
	        int len = -80;
	        byte color;
	        int dOff = 0;
	        int wCur = w;
	        int hCur;
	        do {
	            hCur = h;
	            int dOff2 = dOff;
	            if (len == -80) {
	                len = srcData[offset++];
	                if ((len & 0x80) != 0) {
	                    len = -128 + (len & 0x7f);
	                }
	            }
	            boolean stop = false;
	            for (; !stop;) {
	                if (len >= 0) {
	                    color = srcData[offset++];
	                    do {
	                        dstData[dOff2] = color;
	                        dOff2 += w;
	                        if (--hCur == 0) {
	                            if (--len < 0) {
	                                len = -80;
	                            } else {
	                                offset--;
	                            }
	                            stop = true;
	                        }
	                    } while (!stop && (--len >= 0));
	                } else {
	                    do {
	                        dstData[dOff2] = srcData[offset++];
	                        dOff2 += w;
	                        if (--hCur == 0) {
	                            if (++len == 0) {
	                                len = -80;
	                            }
	                            stop = true;
	                        }
	                    } while (!stop && ++len != 0);
	                }
	                if (!stop) {
	                    len = srcData[offset++];
	                    if ((len & 0x80) != 0) {
	                        len = -128 + (len & 0x7f);
	                    }
	                }
	            }
	            dOff++;
	        } while (--wCur > 0);
	        return dstData;
	    }

Bearbeitet von Devilmarkus
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...