Devilmarkus Geschrieben 25. April 2016 Geschrieben 25. April 2016 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 Zitieren
Devilmarkus Geschrieben 25. April 2016 Autor Geschrieben 25. April 2016 (bearbeitet) 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 25. April 2016 von Devilmarkus Zitieren
Empfohlene Beiträge
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.