GSLA Encoder - WIP - I think all that's left to do is to emit source bank skip opcodes, so the player can deal deal with data > 64K in size

This commit is contained in:
JASON-6700K\jandersen 2020-07-19 15:05:17 -04:00
parent 0764a030e6
commit 6956281d1e
3 changed files with 58 additions and 125 deletions

View File

@ -8,8 +8,27 @@
#include "bctypes.h" #include "bctypes.h"
//
// This is written specifically for the GSLA, so opcodes emitted are designed
// to work with our version of a run/skip/dump
//
//
//Command Word, encoded low-high, what the bits mean:
//
// xxx_xxxx_xxxx_xxx is the number of bytes 1-16384 to follow (0 == 1 byte)
//
//%0xxx_xxxx_xxxx_xxx1 - Copy Bytes - straight copy bytes
//%1xxx_xxxx_xxxx_xxx1 - Skip Bytes - skip bytes / move the cursor
//%1xxx_xxxx_xxxx_xxx0 - Dictionary Copy Bytes from frame buffer to frame buffer
//
//%0000_0000_0000_0000- Source Skip -> Source pointer skips to next bank of data
//%0000_0000_0000_0010- End of Frame - end of frame
//%0000_0000_0000_0110- End of Animation / End of File / no more frames
//
#define MAX_DICTIONARY_SIZE (32 * 1024) #define MAX_DICTIONARY_SIZE (32 * 1024)
#define MAX_STRING_SIZE (16383) #define MAX_STRING_SIZE (16384)
// //
// Yes This is a 32K Buffer, of bytes, with no structure to it // Yes This is a 32K Buffer, of bytes, with no structure to it
// //
@ -235,11 +254,11 @@ int Old_LZB_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSiz
// Return new dictionarySize // Return new dictionarySize
static int AddDictionary(const DataString& data, int dictionarySize) static int AddDictionary(const DataString& data, int dictionarySize)
{ {
//int dataIndex = 0; int dataIndex = 0;
//while ((dictionarySize < MAX_DICTIONARY_SIZE) && (dataIndex < data.size)) while (dataIndex < data.size)
//{ {
// pDictionary[ dictionarySize++ ] = data.pData[ dataIndex++ ]; pDictionary[ dictionarySize++ ] = data.pData[ dataIndex++ ];
//} }
dictionarySize += data.size; dictionarySize += data.size;
@ -537,10 +556,18 @@ static int ConcatLiteral(unsigned char *pDest, DataString& data)
int opCode = pDest[0]; int opCode = pDest[0];
opCode |= (int)(((pDest[1])&0x7F)<<8); opCode |= (int)(((pDest[1])&0x7F)<<8);
opCode>>=1;
opCode+=1;
// opCode contains the length of the literal that's already encoded
int skip = opCode; int skip = opCode;
opCode += outSize; opCode += outSize;
// Opcode // Opcode
opCode -= 1;
opCode <<=1;
opCode |= 1;
*pDest++ = (unsigned char)(opCode & 0xFF); *pDest++ = (unsigned char)(opCode & 0xFF);
*pDest++ = (unsigned char)((opCode >> 8) & 0x7F); *pDest++ = (unsigned char)((opCode >> 8) & 0x7F);
@ -566,9 +593,15 @@ static int EmitLiteral(unsigned char *pDest, DataString& data)
// Return Size // Return Size
int outSize = 2 + (int)data.size; int outSize = 2 + (int)data.size;
// Opcode unsigned short length = (unsigned short)data.size;
*pDest++ = (unsigned char)(data.size & 0xFF); length -= 1;
*pDest++ = (unsigned char)((data.size >> 8) & 0x7F);
unsigned short opcode = length<<1;
opcode |= 0x0001;
// Opcode out
*pDest++ = (unsigned char)( opcode & 0xFF );
*pDest++ = (unsigned char)(( opcode>>8)&0xFF);
// Literal Data // Literal Data
for (int idx = 0; idx < data.size; ++idx) for (int idx = 0; idx < data.size; ++idx)
@ -590,12 +623,22 @@ static int EmitReference(unsigned char *pDest, int dictionaryOffset, DataString&
// Return Size // Return Size
int outSize = 2 + 2; int outSize = 2 + 2;
// Opcode unsigned short length = (unsigned short)data.size;
*pDest++ = (unsigned char)(data.size & 0xFF); length -= 1;
*pDest++ = (unsigned char)((data.size >> 8) & 0x7F) | 0x80;
*pDest++ = (unsigned char)(dictionaryOffset & 0xFF); unsigned short opcode = length<<1;
*pDest++ = (unsigned char)((dictionaryOffset>>8) & 0xFF); opcode |= 0x8000;
// Opcode out
*pDest++ = (unsigned char)( opcode & 0xFF );
*pDest++ = (unsigned char)(( opcode>>8)&0xFF);
// Destination Address out
unsigned short address = (unsigned short)dictionaryOffset;
address += 0x2000; // So we don't have to add $2000 in the animation player
*pDest++ = (unsigned char)(address & 0xFF);
*pDest++ = (unsigned char)((address>>8)&0xFF);
// Clear // Clear
data.pData += data.size; data.pData += data.size;
@ -617,58 +660,6 @@ static void my_memcpy(u8* pDest, u8* pSrc, int length)
} }
} }
//------------------------------------------------------------------------------
//
// Simple Decompress, for validation
//
void LZB_Decompress(unsigned char* pDest, unsigned char* pSource, int destSize)
{
int decompressedBytes = 0;
unsigned char *pOriginalSource = pSource;
while (decompressedBytes < destSize)
{
u16 opcode = *pSource++;
opcode |= ((u16)(*pSource++))<<8;
// printf("%04X:", (unsigned int)(pSource-pOriginalSource));
if (opcode & 0x8000)
{
// Dictionary
opcode &= 0x7FFF;
// Dictionary Copy from the output stream
u16 offset = *pSource++;
offset |= ((u16)(*pSource++))<<8;
const char* overlapped = "";
if ((&pDest[ decompressedBytes ] - &pDest[ offset ]) < opcode)
{
overlapped = "pattern";
}
my_memcpy(&pDest[ decompressedBytes ], &pDest[ offset ], opcode);
decompressedBytes += opcode;
// printf("%04X:Dic %04X %s\n",decompressedBytes, (unsigned int)opcode, overlapped);
}
else
{
// Literal Copy, from compressed stream
memcpy(&pDest[ decompressedBytes ], pSource, opcode);
decompressedBytes += opcode;
pSource += opcode;
// printf("%04X:Lit %04X\n",decompressedBytes, (unsigned int)opcode);
}
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
// Compress a Frame in the GSLA LZB Format // Compress a Frame in the GSLA LZB Format

View File

@ -1,5 +1,5 @@
// //
// LZB Encode / Decode // LZB Encode
// //
#ifndef LZB_H #ifndef LZB_H
#define LZB_H #define LZB_H
@ -9,7 +9,6 @@
// //
int LZB_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSize); int LZB_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSize);
int Old_LZB_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSize); int Old_LZB_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSize);
void LZB_Decompress(unsigned char* pDest, unsigned char* pSource, int destSize);
// //
// LZB Compressor that uses GSLA Opcodes while encoding // LZB Compressor that uses GSLA Opcodes while encoding
@ -17,7 +16,6 @@ void LZB_Decompress(unsigned char* pDest, unsigned char* pSource, int destSize);
int LZBA_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSize, int LZBA_Compress(unsigned char* pDest, unsigned char* pSource, int sourceSize,
unsigned char* pDataStart, unsigned char* pDictionary, unsigned char* pDataStart, unsigned char* pDictionary,
int dictionarySize=0); int dictionarySize=0);
int LZBA_Decompress(unsigned char* pDest, unsigned char* pSource, unsigned char* pDataStart);
#endif // LZB_H #endif // LZB_H

View File

@ -11,8 +11,6 @@
#include "c2_file.h" #include "c2_file.h"
#include "gsla_file.h" #include "gsla_file.h"
#include "lzb.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void helpText() static void helpText()
{ {
@ -130,60 +128,6 @@ int main(int argc, char* argv[])
anim.SaveToFile(pOutfilePath); anim.SaveToFile(pOutfilePath);
} }
#if 0
const std::vector<unsigned char*>& c1Datas = c2data.GetPixelMaps();
// LZB Testing Code, that I should probalby remove from this file
// Just ignore this block of code
#if 1
unsigned char workbuffer[64*1024];
for (int idx = 0; idx < frameCount; ++idx)
{
int compressedSize = LZB_Compress(workbuffer, c1Datas[ idx ], 32 * 1024);
printf("compressedSize = %d\n", compressedSize);
unsigned char validationBuffer[ 32 * 1024 ];
LZB_Decompress(validationBuffer, workbuffer, 32 * 1024);
if (0 == memcmp(c1Datas[ idx ], validationBuffer, 32*1024))
{
printf("Decompression Validated\n");
}
else
{
printf("Decompression Corrupted\n");
}
}
#else
unsigned char workbuffer[64*1024];
unsigned char workbuffer2[64*1024];
for (int idx = 0; idx < frameCount; ++idx)
{
int oldCompressedSize = Old_LZB_Compress(workbuffer2, c1Datas[ idx ], 32 * 1024);
printf("old compressedSize = %d\n", oldCompressedSize);
int compressedSize = LZB_Compress(workbuffer, c1Datas[ idx ], 32 * 1024);
printf("compressedSize = %d\n", compressedSize);
unsigned char validationBuffer[ 32 * 1024 ];
printf("Decompress OLD\n");
LZB_Decompress(validationBuffer, workbuffer2, 32 * 1024);
printf("Decompress NEW\n");
LZB_Decompress(validationBuffer, workbuffer, 32 * 1024);
if (0 == memcmp(c1Datas[ idx ], validationBuffer, 32*1024))
{
printf("Decompression Validated\n");
}
else
{
printf("Decompression Corrupted\n");
}
}
#endif
#endif
} }
} }