LURE: Converted the vgaDecode routine to remove GOTO usage

This commit is contained in:
Paul Gilbert 2011-12-09 12:24:32 +11:00
parent 509cc5f4c4
commit f169e17eca

View file

@ -34,12 +34,18 @@ namespace Lure {
/* Provides the functionality for decoding screens */ /* Provides the functionality for decoding screens */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
/**
* Write a single byte to the output buffer
*/
void PictureDecoder::writeByte(MemoryBlock *dest, byte v) { void PictureDecoder::writeByte(MemoryBlock *dest, byte v) {
if (outputOffset == dest->size()) if (outputOffset == dest->size())
error("Decoded data exceeded allocated output buffer size"); error("Decoded data exceeded allocated output buffer size");
dest->data()[outputOffset++] = v; dest->data()[outputOffset++] = v;
} }
/**
* Writes out a specified byte a given number of times to the output
*/
void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) { void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) {
if (outputOffset + numBytes > dest->size()) if (outputOffset + numBytes > dest->size())
error("Decoded data exceeded allocated output buffer size"); error("Decoded data exceeded allocated output buffer size");
@ -47,6 +53,9 @@ void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) {
outputOffset += numBytes; outputOffset += numBytes;
} }
/**
* Gets a byte from the compressed source using the first data pointer
*/
byte PictureDecoder::DSSI(bool incr) { byte PictureDecoder::DSSI(bool incr) {
if (dataPos > dataIn->size()) if (dataPos > dataIn->size())
error("PictureDecoder went beyond end of source data"); error("PictureDecoder went beyond end of source data");
@ -57,6 +66,9 @@ byte PictureDecoder::DSSI(bool incr) {
return result; return result;
} }
/**
* Gets a byte from the compressed source using the second data pointer
*/
byte PictureDecoder::ESBX(bool incr) { byte PictureDecoder::ESBX(bool incr) {
if (dataPos2 >= dataIn->size()) if (dataPos2 >= dataIn->size())
error("PictureDecoder went beyond end of source data"); error("PictureDecoder went beyond end of source data");
@ -227,56 +239,61 @@ MemoryBlock *PictureDecoder::vgaDecode(MemoryBlock *src, uint32 maxOutputSize) {
CH = ESBX(); CH = ESBX();
CL = 9; CL = 9;
Loc754: // Main decoding loop
AL = DSSI(); bool loopFlag = true;
writeByte(dest, AL); while (loopFlag) {
BP = ((uint16) AL) << 2; AL = DSSI();
writeByte(dest, AL);
BP = ((uint16) AL) << 2;
Loc755: // Inner loop
decrCtr(); for (;;) {
if (shlCarry()) goto Loc761; decrCtr();
decrCtr(); if (shlCarry()) {
if (shlCarry()) goto Loc759; decrCtr();
AL = dataIn->data()[BP]; if (shlCarry()) {
decrCtr();
if (shlCarry())
break;
AL = dataIn->data()[BP + 3];
} else {
decrCtr();
if (shlCarry())
AL = dataIn->data()[BP + 2];
else
AL = dataIn->data()[BP + 1];
}
} else {
decrCtr();
if (shlCarry()) {
AL = (byte) (BP >> 2);
AH = DSSI();
if (AH == 0) {
AL = DSSI();
if (AL == 0) {
// Finally done
loopFlag = false;
break;
} else {
// Keep going
continue;
}
} else {
// Write out byte sequence
writeBytes(dest, AL, AH);
continue;
}
} else {
AL = dataIn->data()[BP];
}
}
Loc758: // Write out the next byte
writeByte(dest, AL); writeByte(dest, AL);
BP = ((uint16) AL) << 2; BP = ((uint16) AL) << 2;
goto Loc755; }
}
Loc759:
AL = (byte) (BP >> 2);
AH = DSSI();
if (AH == 0) goto Loc768;
writeBytes(dest, AL, AH);
goto Loc755;
Loc761:
decrCtr();
if (shlCarry()) goto Loc765;
decrCtr();
if (shlCarry()) goto Loc764;
AL = dataIn->data()[BP+1];
goto Loc758;
Loc764:
AL = dataIn->data()[BP+2];
goto Loc758;
Loc765:
decrCtr();
if (shlCarry()) goto Loc767;
AL = dataIn->data()[BP+3];
goto Loc758;
Loc767:
goto Loc754;
Loc768:
AL = DSSI();
if (AL != 0) goto Loc755;
// Resize the output to be the number of outputed bytes and return it // Resize the output to be the number of outputed bytes and return it
if (outputOffset < dest->size()) dest->reallocate(outputOffset); if (outputOffset < dest->size()) dest->reallocate(outputOffset);