From 1590c05822e5fa08feae58ddea360d06dbe577c6 Mon Sep 17 00:00:00 2001 From: Daveo Date: Sat, 23 Jun 2001 15:33:07 +0000 Subject: [PATCH] --- Utils/MkLevel/pak.cpp | 359 ++++++++++++++++++++++++++++++++++++++++++ Utils/MkLevel/pak.h | 61 +++++++ 2 files changed, 420 insertions(+) create mode 100644 Utils/MkLevel/pak.cpp create mode 100644 Utils/MkLevel/pak.h diff --git a/Utils/MkLevel/pak.cpp b/Utils/MkLevel/pak.cpp new file mode 100644 index 000000000..40da81b94 --- /dev/null +++ b/Utils/MkLevel/pak.cpp @@ -0,0 +1,359 @@ +/*========================================================================= + + PAK.CPP + + Author: Gary Liddon @ Climax (from work by Nick Pelling && Carl Muller) + Created: + Project: Diablo PSX + Purpose: PAK decompress \ compress code + + Copyright (c) 1997 Climax Development Ltd + +===========================================================================*/ + +/*---------------------------------------------------------------------- + Includes + -------- */ + +/* Std Lib + ------- */ + +/* Glib + ---- */ + +/* Local + ----- */ +#include +#include "pak.h" + +/* Graphics + -------- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ +#define UNPAKBUFFERSIZE 4096 +#define STRMAX 80 +#define BUFFERSIZE 30000 +#define TRIGGER 20000 +#define MAXUNIQUE 127 + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ +struct Block +{ + int data[128]; + BOOL blockrep; + int blocksize; + int blockoffset; + + u8 * Dest; + int outsize; + + virtual void fputc(u8 Val) + { + *Dest=Val; + Dest++; + outsize++; + } + + void writeBlock(void); +}; + +struct CountBlock : Block +{ + virtual void fputc(u8 Val) + { + Dest++; + outsize++; + } +}; + +/*---------------------------------------------------------------------- + Vars + ---- */ +static int s_lastAmountOfCompressedData; + +/*---------------------------------------------------------------------- + Function Prototypes + ------------------- */ +static void writeblock(struct block *theblock); + +/*---------------------------------------------------------------------- + Vars + ---- */ +/*---------------------------------------------------------------------- + Data + ---- */ + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void Block::writeBlock(void) +{ + if ((blockrep) && (blocksize == 0)) + { + /* Terminator */ + fputc(128); + fputc(0); + } + else if (blockrep) + { + fputc(blockoffset); + fputc(blocksize); + } + else /* Unique bytes */ + { + fputc(blocksize & 127); + + for (int i = 0; i <= blocksize; i++) + fputc(data[i]); + } + + // Get ready for next block + blockrep = FALSE; + blockoffset = 0; + blocksize = -1; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +static bool memequ(u8 const * p1,u8 const * p2,int size) +{ + bool same; + + same=true; + + for (int f=0;f FORWARDDIST) + end = FORWARDDIST; + + bestoffset = begin; + bestlength = 1; + theptr = buffer + (inpos); + + ptr1 = buffer + (inpos + begin); + + for (offset = begin; offset < 0; offset++) + { + if (*ptr1 == *theptr) + { + if (memequ(ptr1, theptr, bestlength + 1)) + { + bestlength++; + bestoffset = offset; + ptr2 = ptr1 + bestlength; + ptr3 = theptr + bestlength; + + while (*ptr2 == *ptr3) + { + ptr2++; + ptr3++; + bestlength++; + if (bestlength >= end) + break; + } + } + } + + if (bestlength >= end) + { + bestlength = end; + break; + } + + ptr1++; + } + + + if (bestlength < MINBLOCK) + { + /* See if last block is unique */ + + if (theblock.blockrep) /* Flush previous special block */ + { + theblock.writeBlock(); + theblock.data[++theblock.blocksize] = buffer[inpos++]; + } + else + { + /* Add to it */ + + if (theblock.blocksize >= MAXUNIQUE) + theblock.writeBlock(); + + theblock.data[++theblock.blocksize] = buffer[inpos++]; + } + } + else + { + /* We have found a match */ + theblock.writeBlock(); + theblock.blockrep = TRUE; + theblock.blocksize = bestlength; + theblock.blockoffset = bestoffset; + inpos += bestlength; + } + } + + /* Flush buffer */ + + theblock.writeBlock(); + + /* Terminate file */ + + theblock.blockrep = TRUE; + theblock.blocksize = 0; + theblock.blockoffset = 0; + theblock.writeBlock(); + + return(theblock.outsize); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +int PAK_doPak(u8 * Dest,u8 const * buffer,int insize) +{ + Block outBlock; + return(lowLevelPak(Dest,buffer,insize,outBlock)); +} + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +int PAK_findPakSize(u8 const * buffer,int insize) +{ + CountBlock outBlock; + return(lowLevelPak(NULL,buffer,insize,outBlock)); +} + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +int PAK_doUnpak(u8 * Dest,u8 const * Source) +{ + int outsize = 0; + u8 const * originalSource; + + originalSource=Source; + + while (1) /* ie, continue until end mark */ + { + u8 const * From; + + int size; + int ch; + + ch = *Source++; + + if (ch < 128) /* if it is in range {0..127} then */ + { + size = (ch + 1); + From=Source; + Source+=size; + } + else + { + size = *Source++; + + if (size == 0) /* distance == 0 => end of file */ + break; + + From=Dest+(s8)ch; + } + + u8 * endAddr; + endAddr=(u8*)(u32(From)+size); + + outsize += size; + + while (From!=endAddr) + { + *Dest=*From; + Dest++; + From++; + } + } + + s_lastAmountOfCompressedData=Source-originalSource; + + return(outsize); +} + +int PAK_getLastAmountOfDataRead(void) +{ + return(s_lastAmountOfCompressedData); +} + +/*=========================================================================== + end */ + + + + diff --git a/Utils/MkLevel/pak.h b/Utils/MkLevel/pak.h new file mode 100644 index 000000000..f3f5df83f --- /dev/null +++ b/Utils/MkLevel/pak.h @@ -0,0 +1,61 @@ +/*========================================================================= + + PAK.H + + Author: Carl Muller (algorithm Nick Pelling && Carl Muller) + Created: + Project: + Purpose: + + Copyright (c) 1997 Climax Development Ltd + +===========================================================================*/ + +#ifndef __PAK_PAK_H__ +#define __PAK_PAK_H__ + +/*---------------------------------------------------------------------- + Includes + -------- */ + +/* Std Lib + ------- */ + +/* Glib + ---- */ +#include + +/* Local + ----- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ + +/*---------------------------------------------------------------------- + Globals + ------- */ + +/* Vars + ---- */ + +/* Data + ---- */ + +/* Functions + --------- */ +int PAK_doPak(u8 * Dest,u8 const * source,int insize); +int PAK_doUnpak(u8 * Dest,u8 const * Source); +int PAK_findPakSize(u8 const * souce,int insize); +int PAK_getLastAmountOfDataRead(void); + +/*---------------------------------------------------------------------- */ + +#endif /* __PAK_PAK_H__ */ + +/*=========================================================================== + end */