'=========================================================================== ' Subject: EX-PACK COMPRESSOR V0.80 Date: 11-28-97 (22:10) ' Author: Andrew Nagy Code: QB, PDS ' Origin: nagyi@bigfoot.com Packet: PACKER.ABC '=========================================================================== DEFINT A-Z DECLARE SUB Test () 'this is not true test, just some infof about the packed file... DECLARE SUB Info () 'info about bugtesters, betatesters, so... DECLARE SUB Help () 'this screen shows if nothing entered for commandline DECLARE SUB SpecEd () 'this sub is the SpecialEdition registrations place DECLARE SUB PutByte (a) 'by Rich Geldreich DECLARE SUB PutCode (a) 'by Rich Geldreich DECLARE SUB Rebuild.Table (New.Entries) 'by Rich Geldreich DECLARE FUNCTION GetByte () 'by Rich Geldreich DECLARE SUB Hash (Prefix, Suffix, Index, Found) 'by Rich Geldreich DECLARE SUB GetArg () 'gets the commandline parameters DECLARE FUNCTION ExePath$ () 'EXE running from... '$INCLUDE: 'c:\qb\qb.bi' DIM SHARED Arg$(0 TO 85) DIM SHARED spced$ 'the $ of the encoded-decoded SpecialEdition info CONST True = -1, False = 0 'by Rich Geldreich DIM SHARED Prefix(6576), Suffix(6576), Code(6576) 'by Rich Geldreich DIM SHARED Used(4096) 'by Rich Geldreich DIM SHARED ver$ 'the version# of EX-Pack DIM SHARED comment$ 'comment like "FINAL!" or "FIRST BETA!!" or something like this... '-================================================================== ver$ = "0.80" 'version # (shows everywhere...) comment$ = " FINAL!" 'comment if available (shows everywhere!!) '-================================================================== DIM SHARED InBuffer$, IAddress, IEndAddress, Iseg 'by Rich Geldreich DIM SHARED OutBuffer$, OStartAddress, OAddress, OEndAddress, Oseg 'by Rich Geldreich DIM SHARED CodeSize, CurrentBit, Char& 'by Rich Geldreich DIM SHARED Shift(12) AS LONG 'by Rich Geldreich FOR a = 0 TO 12: READ Shift(a): NEXT 'by Rich Geldreich DATA 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192 'by Rich Geldreich 'dunno what is that.... x = 24 LOCATE , , 1 IF POS(0) <> 1 THEN PRINT dae$ = STRING$(10, 0) 'date buffer (puts in header of packed file) by me. InBuffer$ = STRING$(4000, 0) 'input buffer OutBuffer$ = STRING$(4000, 0) 'output buffer 1 a& = SADD(OutBuffer$) a& = a& - 65536 * (a& < 0) Oseg = VARSEG(OutBuffer$) + (a& \ 16) 'Segment of buffer OAddress = (a& MOD 16) 'Current address in disk buffer OEndAddress = OAddress + 4000 'End address of buffer OStartAddress = OAddress 'Start of buffer CLS ' here opens the SpecialEdition keyfile OPEN "expc.spc" FOR BINARY AS #8 IF LOF(8) = 0 THEN lfas = 1: CLOSE #8: GOTO tovabb ELSE CLOSE #8 'is it a true file????? OPEN "expc.spc" FOR INPUT AS #8 INPUT #8, spced$ sss$ = spced$ CLOSE #8 tovabb: IF lfas = 1 THEN KILL "expc.spc" ELSE 'it isn't exist File$ = COMMAND$ GetArg 'gets commandline params... 'PRINT "The program running is: "; arg$(0) IF Arg$(1) = "" THEN 'no commanline Help END ELSE END IF File$ = Arg$(1) 'first parameter is file... IF MID$(File$, LEN(File$), 1) = "." THEN a = 1 'havent got extension... IF a = 1 THEN PRINT "File without extension cannot be packed!!" 'WOW!!!!!! File$ = RTRIM$(File$) 'some tunings.. File$ = LTRIM$(File$) out$ = File$ MID$(out$, LEN(File$), 1) = "_" 'output filename (ex. qb.ex_) 'here are the commandline parameters IF UCASE$(Arg$(1)) = "/M" OR UCASE$(Arg$(2)) = "/M" OR UCASE$(Arg$(3)) = "/M" OR UCASE$(Arg$(4)) = "/M" THEN GOTO Demo IF UCASE$(Arg$(1)) = "/B" OR UCASE$(Arg$(2)) = "/B" OR UCASE$(Arg$(3)) = "/B" OR UCASE$(Arg$(4)) = "/B" THEN Info ELSE Tst = 0 IF UCASE$(Arg$(1)) = "/A" OR UCASE$(Arg$(2)) = "/A" OR UCASE$(Arg$(3)) = "/A" OR UCASE$(Arg$(4)) = "/A" THEN SpecEd ELSE a = a IF UCASE$(Arg$(2)) = "/T" OR UCASE$(Arg$(3)) = "/T" OR UCASE$(Arg$(4)) = "/T" THEN Test 'opens files OPEN File$ FOR BINARY AS #1 FileLength& = LOF(1) afl = LEN(FileLength&) size$ = STRING$(lafl, 0) 'Is it there? IF FileLength& = 0 THEN CLOSE #1 KILL COMMAND$ PRINT COMMAND$; " not found" END END IF 'Open output file OPEN out$ FOR BINARY AS #2 'Is it already there? IF LOF(2) <> 0 THEN 'Kill output file and reopen it CLOSE #2 CLS PRINT "File called " + out$ + " already exist." PRINT "Overwrite/Skip (O/S) :" 'LOCATE 2, 24 DO IF UCASE$(INKEY$) = "O" THEN GOTO xxxx IF UCASE$(INKEY$) = "S" THEN RESET: PRINT "Skipped.": END 'ELSE PRINT "Wrong answer!!": RESET: END LOOP xxxx: KILL out$ OPEN out$ FOR BINARY AS #2 END IF aa = LEN(Arg$(1)) ax$ = File$ + SPACE$(12 - aa) 'filename in header id$ = "EXP" + UCASE$(ver$) 'ID of an EX-Packed file 'more commandline params... IF UCASE$(Arg$(2)) = "/C" OR UCASE$(Arg$(3)) = "/C" OR UCASE$(Arg$(4)) = "/C" THEN crc$ = "N" ELSE crc$ = "Y" IF UCASE$(Arg$(2)) = "/D" OR UCASE$(Arg$(3)) = "/D" OR UCASE$(Arg$(4)) = "/D" THEN ban = 0 ELSE ban = 1 IF UCASE$(Arg$(2)) = "/S" OR UCASE$(Arg$(3)) = "/S" OR UCASE$(Arg$(4)) = "/S" THEN tui = 0 ELSE tui = 1 IF UCASE$(Arg$(2)) = "/H" OR UCASE$(Arg$(3)) = "/H" OR UCASE$(Arg$(4)) = "/H" THEN spced = 0 ELSE IF spced$ <> "" THEN spced = 1 IF UCASE$(Arg$(2)) = "/T" OR UCASE$(Arg$(3)) = "/T" OR UCASE$(Arg$(4)) = "/T" THEN Test '---------------- dae$ = DATE$ 'woooooooow!!!!! puts everything out into file! PUT #2, , id$ 'like 'EXP0.76' PUT #2, , ax$ 'real name of file in 12 characters max PUT #2, , dae$ 'actual date PUT #2, , crc$ 'joke now, maybe I will make here something later... '---------------- 'CurrentLoc& - position in input file CurrentLoc& = 2 'END CLS 'Compression codes: 'Code 256 = end of file 'Code 257 = increase code size 'Code 258 = rebuild table 'Code 259 - 4095 = available for strings StartCode = 259 'First LZW code that is available NextCode = 259 'The maximum code that can be represented in 9 bits MaxCode = 512 'Start with 9 bit code size CodeSize = 9 'Current bit position in Char& - use for PutCode CurrentBit = 0 'Char& is a temporary buffer; accumulates codes from main program and 'puts them in the output file once complete bytes have been 'built Char& = 0 GOSUB ClearTable 'Get first byte from file(it's a special case) Prefix = GetByte IF tui = 0 THEN GOTO t0 'GOTO hdr2 IF spced$ = "" THEN GOTO hdr2 ELSE GOTO hdr1 'if no SpecialEdition info 'then goes to normal line else 'goes to Special line hdr1: 'decodes encoded SpecialEdition info FOR tt = 1 TO LEN(spced$) yq% = 0 xq% = ASC(MID$(spced$, tt, 1)) 'PRINT x% IF (xq% > 64 AND xq% < 91) OR (xq% > 96 AND xq% < 123) THEN yq% = 13 xq% = xq% - yq% IF xq% < 97 AND xq% > 83 THEN xq% = xq% + 26 ELSE IF xq% < 65 THEN xq% = xq% + 26 END IF MID$(spced$, tt, 1) = CHR$(xq%) NEXT tt decoded$ = spced$ '================================================================== IF spced = 0 THEN GOTO tib 'whats this?????????????? ss$ = sss$ + SPACE$(24 - LEN(sss$)) 'password buffer be$ = "Y" 'marks password exist for unpacker program... PUT #2, , be$ 'mark PUT #2, , ss$ 'encoded password '================================================================== ' prints the special line tib: aaa = LEN("EX-Pack v" + ver$ + comment$ + " SpecialEdition for: " + decoded$ + " by SNPG") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " by SNPG" + " ³SpecialEdition for: " + decoded$ + "³" GOTO t0: hdr2: 'prints normal line... aaa = LEN("EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group" be$ = "N" PUT #2, , be$ t0: COLOR 7, 0 IF crc$ = "N" THEN GOTO noc PRINT "Adding CRC+ (tm) ..." 'joke FOR azz& = 1 TO 500000 NEXT azz& noc: LOCATE 2, 1: PRINT "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿" LOCATE 3, 1: PRINT "³ Compressing "; File$ PRINT : PRINT : PRINT "" 'First line to start updating statistics y = CSRLIN - 3 'Main compression loop LOCATE 3, 27: COLOR 7: PRINT " ³0% ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± 100%³": COLOR 7 DO LOCATE , , 0 DO IF CurrentLoc& > FileLength& THEN PutCode Prefix PutCode 256 PutCode 0: PutCode 0 OutBuffer$ = LEFT$(OutBuffer$, OAddress - OStartAddress) LOCATE y, 1 'PRINT "Bytes In:"; CurrentLoc&; (100& * CurrentLoc&) \ FileLength&; "%" BytesOut& = LOF(2) + (OAddress - OStartAddress) 'PRINT "Bytes Out:"; BytesOut& PRINT "³ Packing done. " PRINT "³ Total Compression:"; 100 - ((100& * BytesOut&) \ CurrentLoc&); "% " PUT #2, , OutBuffer$ CLOSE IF tui = 0 THEN GOTO t2 IF ban = 1 THEN GOTO okl ELSE SYSTEM okl: COLOR 15: LOCATE 9: PRINT " ±±±±±±± ±±±±± ±±± ±± ±±±±±±± ±± " PRINT " ±± ±± ± ± ±± ± ±± ± ±±±± " PRINT " ±± ± ± ± ±± ± ±± ± ±±±± " PRINT " ±± ± ± ± ±± ± ±± ±±±± ±± " PRINT " ±± ± ± ± ±± ± ±± ± ±± " PRINT " ±± ±± ± ± ±± ± ±± ± " PRINT " ±±±±±±± ±±±±± ±± ±±± ±±±±±±± ±± " t2: COLOR 7, 0 SYSTEM ELSE Suffix = GetByte CurrentLoc& = CurrentLoc& + 1 'We now have a Prefix:Suffix to search for. 'If the search fails, put the Prefix in the output file 'and set the Prefix equal to the character which caused 'the failure. Hash Prefix, Suffix, Index, Found IF Found = True THEN Prefix = Code(Index) 'update how many times this string was used Used(Prefix) = Used(Prefix) + 1 END IF END IF LOOP WHILE Found = True 'only increase the code size when required DO WHILE Prefix >= MaxCode AND CodeSize < 12 PutCode 257 MaxCode = MaxCode * 2 CodeSize = CodeSize + 1 LOOP PutCode Prefix 'Put the new string into the hash table. Prefix(Index) = Prefix Suffix(Index) = Suffix Code(Index) = NextCode 'remember this string's code 'Prefix is now equal to the character that caused the failure now. Prefix = Suffix NextCode = NextCode + 1 'if there are too many strings then rebuild the encoding table IF NextCode > 4096 THEN PutCode 258 'send rebuild table code to decompressor Rebuild.Table New.Entries NextCode = New.Entries + StartCode IF NextCode > 4096 THEN GOSUB ClearTable NextCode = StartCode 'reset NextCode to top of tree END IF CodeSize = 9 MaxCode = 512 END IF 'let the impatient user know we haven't hung up (yet!) PrintCounter = PrintCounter + 1 'see if time to update the IF PrintCounter = 512 THEN 'screen LOCATE y, 1 PRINT "³ Packed :"; (100& * CurrentLoc&) \ FileLength&; "%" LOCATE 4, 28: PRINT "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´" 'LOCATE 5, 28: PRINT "³" BytesOut& = LOF(2) + (OAddress - OStartAddress) IF tui = 0 THEN GOTO t1 x = x + 1 bbbbb = (((100& * CurrentLoc&) \ FileLength&) * 20) \ 64 LOCATE 3, bbbbb + 32: COLOR 15: PRINT "±": COLOR 7 t1: LOCATE 5: PRINT "³ Compression:"; 100 - ((100& * BytesOut&) \ CurrentLoc&); "% " LOCATE 5, 68: PRINT "³" LOCATE 6: PRINT "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ" PrintCounter = 0 END IF LOOP 'clears the hash table ClearTable: FOR a = 0 TO 6576 Prefix(a) = -1 Suffix(a) = -1 Code(a) = -1 NEXT RETURN Demo: 'plugin part, maybe more plugins CLS OPEN "demo.plg" FOR BINARY AS #1 d& = LOF(1) IF d& = 0 THEN RESET: PRINT "A demo may be here... Get the plugin called 'DEMO.PLG' !": KILL "demo.plg": END ELSE SHELL "ren demo.plg demo.exe" SHELL "demo" SHELL "ren demo.exe demo.plg" PRINT "Plugin running ended..." FUNCTION ExePath$ STATIC DIM Regs AS RegType 'Allocate space for TYPE ' RegType Regs.ax = &H5100 'DOS function 51h INTERRUPT &H21, Regs, Regs ' Get PSP Address DEF SEG = Regs.bx 'Regs.bx returns PSP sgmnt. EnvSeg% = PEEK(&H2C) + PEEK(&H2D) * 256 'Get environment address DEF SEG = EnvSeg% 'Set environment address DO Byte% = PEEK(Offset%) 'Take a byte IF Byte% = 0 THEN 'Items are ASCIIZ Count% = Count% + 1 ' terminated IF Count% AND EXEFlag% THEN 'EXE also ASCIIZ terminated EXIT DO 'Exit at the end ELSEIF Count% = 2 THEN 'Last entry in env. is EXEFlag% = -1 ' terminated with two Offset% = Offset% + 2 ' NULs. Two bytes ahead END IF ' is the EXE file name. ELSE 'If Byte% <> 0, reset Count% = 0 ' zero counter IF EXEFlag% THEN 'If EXE name found, Temp$ = Temp$ + CHR$(Byte%) ' build string END IF END IF Offset% = Offset% + 1 'To grab next byte... LOOP 'Do it again DEF SEG 'Reset default segment ExePath$ = Temp$ 'Return value Temp$ = "" 'Clean up END FUNCTION '----------------------------------------------------------------------- SUB GetArg Arg$(0) = ExePath$ IF COMMAND$ = "" THEN EXIT SUB i = 1: j = 1 DO UNTIL i >= LEN(COMMAND$) WHILE MID$(COMMAND$, i, 1) <> " " AND MID$(COMMAND$, i, 1) <> "" Arg$(j) = Arg$(j) + MID$(COMMAND$, i, 1) i = i + 1 WEND i = i + 1: j = j + 1 LOOP END SUB 'Reads one byte from the input buffer, and fills the buffer if it's emty. FUNCTION GetByte STATIC IF IAddress = IEndAddress THEN GET #1, , InBuffer$ a& = SADD(InBuffer$) a& = a& - 65536 * (a& < 0) Iseg = VARSEG(InBuffer$) + (a& \ 16) IAddress = (a& MOD 16) IEndAddress = IAddress + 4000 END IF DEF SEG = Iseg GetByte = PEEK(IAddress) IAddress = IAddress + 1 END FUNCTION SUB GetPal (Attr%, Red%, Green%, Blue%) 'SUB to get a color attribute OUT &H3C7, Attr% OUT &H3C8, Attr% Red% = INP(&H3C9) Green% = INP(&H3C9) Blue% = INP(&H3C9) END SUB 'Attempts to finds a prefix:suffix string. SUB Hash (Prefix, Suffix, Index, Found) Index = (Prefix * 256& XOR Suffix) MOD 6577 'XOR hashing IF Index = 0 THEN 'is Index lucky enough to be 0? Offset = 1 'Set offset to 1, because 6577-0=6577 ELSE Offset = 6577 - Index END IF DO 'until we find a match or don't IF Code(Index) = -1 THEN 'is there nothing here? Found = False 'yup, not found EXIT SUB 'is this entry what we're looking for? ELSEIF Prefix(Index) = Prefix AND Suffix(Index) = Suffix THEN Found = True 'yup, found EXIT SUB ELSE 'retry until we find what were looking for or we find a blank 'entry Index = Index - Offset IF Index < 0 THEN 'is index too far down? Index = Index + 6577 'yup, bring it up then END IF END IF LOOP END SUB SUB Help COLOR 7, 0 CLS IF spced$ = "" THEN GOTO hdrrr2 ELSE GOTO hdrrr1 hdrrr1: FOR tt = 1 TO LEN(spced$) y% = 0 x% = ASC(MID$(spced$, tt, 1)) 'PRINT x% IF (x% > 64 AND x% < 91) OR (x% > 96 AND x% < 123) THEN y% = 13 x% = x% - y% IF x% < 97 AND x% > 83 THEN x% = x% + 26 ELSE IF x% < 65 THEN x% = x% + 26 END IF MID$(spced$, tt, 1) = CHR$(x%) NEXT tt decoded$ = spced$ aaa = LEN("EX-Pack v" + ver$ + comment$ + " SpecialEdition for: " + decoded$ + " by SNPG ") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " by SNPG" + " ³SpecialEdition for: " + decoded$ + "³" GOTO huha hdrrr2: aaa = LEN("EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group" huha: COLOR 7, 0 PRINT "Build information : 08-12-1997"; " Build 1" PRINT COLOR 15, 0 PRINT "Syntax : expc.exe filename.ext /options" COLOR 7, 0 PRINT PRINT "Options :" PRINT "/c - Don't add CRC+ Recovery" PRINT "/h - Don't add SpecialEdition info into header (24 bytes smaller file)" PRINT "/d - Don't shows the big DONE! bannner on the end." PRINT "/s - Standard output mode, no friendly TUI." PRINT "/a - (*) SpecialEdition registarion." PRINT "/t - Tests the header of packed file" PRINT PRINT "/b - About the authors, BETA testers." PRINT "/m - A waveing flag. Try it!" PRINT PRINT PRINT "For files with a (*) sign, see the documentation." END END SUB SUB Info CLS IF spced$ = "" THEN GOTO hdrr2 ELSE GOTO hdrr1 hdrr1: FOR tt = 1 TO LEN(spced$) y% = 0 x% = ASC(MID$(spced$, tt, 1)) 'PRINT x% IF (x% > 64 AND x% < 91) OR (x% > 96 AND x% < 123) THEN y% = 13 x% = x% - y% IF x% < 97 AND x% > 83 THEN x% = x% + 26 ELSE IF x% < 65 THEN x% = x% + 26 END IF MID$(spced$, tt, 1) = CHR$(x%) NEXT tt decoded$ = spced$ aaa = LEN("EX-Pack v" + ver$ + comment$ + " SpecialEdition for: " + decoded$ + " by SNPG ") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " by SNPG" + " ³SpecialEdition for: " + decoded$ + "³" 'RESET 'END GOTO tovbb hdrr2: aaa = LEN("EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group" tovbb: COLOR 7, 0 COLOR 15 PRINT "About the authors and the beta testers:" COLOR 7 PRINT PRINT "Authors:" PRINT "Andras Nagy - TUI, code, header,so.." PRINT "Peter Radics - Tips, testing." PRINT PRINT "Beta testers:" PRINT "Ferenc Sorosics - Wide testing!! Explored many bugs!" PRINT PRINT "Contact us:" PRINT "Info & Updates : http://www.mygale.org/~sgpr/our.htm" PRINT "Electronic Mail: nagyi@bigfoot.com" END END SUB 'Throws a byte into the output buffer and writes the buffer if it's full. SUB PutByte (a) STATIC IF OAddress = OEndAddress THEN PUT #2, , OutBuffer$ OAddress = OStartAddress END IF DEF SEG = Oseg POKE OAddress, a OAddress = OAddress + 1 END SUB 'Throws one multi-bit code to the output file. SUB PutCode (a) STATIC SHARED MaxCode IF a >= MaxCode THEN STOP Char& = Char& + a * Shift(CurrentBit) CurrentBit = CurrentBit + CodeSize DO WHILE CurrentBit > 7 PutByte Char& AND 255 Char& = Char& \ 256 CurrentBit = CurrentBit - 8 LOOP END SUB 'This is the "experimental" part of the program. This procedure eliminates 'any strings which are not used in the encoding table: the usual result of 'doing this is greater compression. 'It isn't documented well yet... I'm still working on it. SUB Rebuild.Table (New.Entries) DIM p(4096), S(4096), U(4096) AS LONG, Pn(4096), c(4096) DIM Location(4096) SHARED StartCode, MaxCode, Prefix Num.Entries = 0 FOR a = 0 TO 6576 c = Code(a) IF c <> -1 THEN 'valid code? IF Used(c) > 0 THEN 'was it used at all? Used(c) = 0 p = Prefix(a): S = Suffix(a) p(Num.Entries) = p 'put it into a temporary table S(Num.Entries) = S U(Num.Entries) = p * 4096& + S c(c) = Num.Entries Num.Entries = Num.Entries + 1 END IF END IF NEXT Num.Entries = Num.Entries - 1 FOR a = 0 TO Num.Entries Pn(a) = a NEXT 'sort the table according to it's prefix:suffix Mid = Num.Entries \ 2 DO FOR a = 0 TO Num.Entries - Mid IF U(Pn(a)) > U(Pn(a + Mid)) THEN SWAP Pn(a), Pn(a + Mid) Swap.Flag = True CompareLow = a - Mid CompareHigh = a DO WHILE CompareLow >= 0 IF U(Pn(CompareLow)) > U(Pn(CompareHigh)) THEN SWAP Pn(CompareLow), Pn(CompareHigh) CompareHigh = CompareLow CompareLow = CompareLow - Mid ELSE EXIT DO END IF LOOP END IF NEXT Mid = Mid \ 2 LOOP WHILE Mid > 0 FOR a = 0 TO Num.Entries Location(Pn(a)) = a NEXT 'clear the old hash table FOR a = 0 TO 6576 Prefix(a) = -1 Suffix(a) = -1 Code(a) = -1 NEXT 'put each prefix:suffix into the hash table FOR A1 = 0 TO Num.Entries a = Pn(A1) p = p(a) S = S(a) IF p >= StartCode THEN 'is it pointing twards a string? p = StartCode + Location(c(p)) 'yup; update the pointer END IF IF S >= StartCode THEN S = StartCode + Location(c(S)) END IF 'where does this prefix:suffix go? Hash p, S, Index, 0 'put it there Prefix(Index) = p Suffix(Index) = S Code(Index) = A1 + StartCode NEXT '# of entries in the hash table now New.Entries = Num.Entries + 1 END SUB SUB SetPal (Attr%, Red%, Green%, Blue%) 'SUB to set a color attribute OUT &H3C7, Attr% OUT &H3C8, Attr% OUT &H3C9, Red% OUT &H3C9, Green% OUT &H3C9, Blue% END SUB SUB SpecEd x: CLS COLOR 15, 3: PRINT "SpecialEdition Registration v1.05 for EX-Pack v0.76g and above " COLOR 7, 0 PRINT INPUT "Enter name (Min. 5, max. 24 chars) : ", spa$ IF spa$ = "" THEN PRINT "Aborted.": END IF LEN(spa$) < 5 THEN PRINT "You must enter minimum 5 characters.": END IF LEN(spa$) > 24 THEN PRINT "You must enter maximum 24 characters.": END Tst$ = spa$ INPUT "Enter key for name: ", spb$ GOTO ROT13 bn: IF spb$ = Tst$ THEN PRINT "Key OK!! SpecialEdition info saved into 'EXPC.SPC'!" OPEN "expc.spc" FOR OUTPUT AS #5 WRITE #5, spb$ CLOSE #5 END ELSE BEEP: COLOR 12: PRINT "Wrong key!!!!": END END IF ROT13: FOR tt = 1 TO LEN(Tst$) y% = 0 x% = ASC(MID$(Tst$, tt, 1)) 'PRINT x% IF (x% > 64 AND x% < 91) OR (x% > 96 AND x% < 123) THEN y% = 13 x% = x% - y% IF x% < 97 AND x% > 83 THEN x% = x% + 26 ELSE IF x% < 65 THEN x% = x% + 26 END IF MID$(Tst$, tt, 1) = CHR$(x%) NEXT tt GOTO bn END SUB SUB Test 'UNDER CONSTRUCTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CLS IF spced$ = "" THEN GOTO hdrrrr2 ELSE GOTO hdrrrr1 hdrrrr1: FOR tt = 1 TO LEN(spced$) y% = 0 x% = ASC(MID$(spced$, tt, 1)) 'PRINT x% IF (x% > 64 AND x% < 91) OR (x% > 96 AND x% < 123) THEN y% = 13 x% = x% - y% IF x% < 97 AND x% > 83 THEN x% = x% + 26 ELSE IF x% < 65 THEN x% = x% + 26 END IF MID$(spced$, tt, 1) = CHR$(x%) NEXT tt decoded$ = spced$ aaa = LEN("EX-Pack v" + ver$ + comment$ + " SpecialEdition for: " + decoded$ + " by SNPG ") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " by SNPG" + " ³SpecialEdition for: " + decoded$ + "³" 'RESET 'END GOTO tovbbb hdrrrr2: aaa = LEN("EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group") aab = 80 - aaa COLOR 15, 3: PRINT SPACE$(aaa + aab) LOCATE 1, 1: PRINT "EX-Pack v" + ver$ + comment$ + " based on LZW by the SigmaNetworks Programming Group" tovbbb: COLOR 15, 0: PRINT "Testing archive header..." COLOR 7, 0 OPEN Arg$(1) FOR BINARY AS #6 id$ = STRING$(7, 0) ax$ = STRING$(12, 0) crc$ = STRING$(1, 0) dt$ = STRING$(10, 0) size& = LOF(6) GET #6, , id$ PRINT "Header version : "; id$ IF id$ = "EXP0.80" THEN id$ = "EXP0.76" IF id$ = "EXP0.76" THEN GOTO oksi ELSE RESET: GOTO hujjaj hujjaj: OPEN Arg$(1) FOR BINARY AS #5 id$ = STRING$(8, 0) ax$ = STRING$(12, 0) crc$ = STRING$(1, 0) dt$ = STRING$(10, 0) size& = LOF(5) GET #5, , id$ PRINT "Header version : "; id$ IF id$ = "EXP0.45A" OR id$ = "EXP0.50A" OR id$ = "EXP0.60A" OR id$ = "EXP0.70B" OR id$ = "EXP0.76G" THEN GOTO oksi ELSE RESET: PRINT "Not a valid packed file.": END oksi: IF id$ = "EXP0.45A" THEN GET #5, , ax$ PRINT "Packed file name : "; ax$ PRINT "Packed size :"; size&; "bytes" END END IF IF id$ = "EXP0.50A" THEN GET #5, , ax$ GET #5, , dt$ PRINT "Packed file name : "; ax$ PRINT "Packed on date : "; dt$ PRINT "Packed size :"; size&; "bytes" END END IF IF id$ = "EXP0.60A" THEN GET #5, , ax$ GET #5, , dt$ PRINT "Packed file name : "; ax$ PRINT "Packed on date : "; dt$ PRINT "CRC+ Recovery : Present! (Built in...)" PRINT "Packed size :"; size&; "bytes" END END IF IF id$ = "EXP0.70B" THEN GET #5, , ax$ GET #5, , dt$ GET #5, , crc$ PRINT "Packed file name : "; ax$ PRINT "Packed on date : "; dt$ IF crc$ = "Y" THEN crc$ = "Present!" PRINT "CRC+ Recovery : "; crc$ PRINT "Packed size :"; size&; "bytes" END END IF IF id$ = "EXP0.76G" THEN GET #5, , ax$ GET #5, , dt$ GET #5, , crc$ IF spced$ <> "" THEN GET #5, , spccode$ ELSE PRINT "Packed file name : "; ax$ PRINT "Packed on date : "; dt$ IF crc$ = "Y" THEN crc$ = "Present!" PRINT "CRC+ Recovery : "; crc$ PRINT "Packed size :"; size&; "bytes" END END IF IF id$ = "EXP0.76" THEN GET #6, , ax$ GET #6, , dt$ GET #6, , crc$ ssss$ = STRING$(1, 0) GET #6, , ssss$ IF ssss$ = "N" THEN GOTO nincsn IF ssss$ = "Y" THEN GOTO vann ELSE GOTO nincsn vann: bevan$ = STRING$(24, 0) GET #6, , bevan$ PRINT "Packed file name : "; ax$ PRINT "Packed on date : "; dt$ IF crc$ = "Y" THEN crc$ = "Present!" PRINT "CRC+ Recovery : "; crc$ PRINT "Packed size :"; size&; "bytes" FOR tt = 1 TO LEN(bevan$) y% = 0 x% = ASC(MID$(bevan$, tt, 1)) 'PRINT x% IF (x% > 64 AND x% < 91) OR (x% > 96 AND x% < 123) THEN y% = 13 x% = x% - y% IF x% < 97 AND x% > 83 THEN x% = x% + 26 ELSE IF x% < 65 THEN x% = x% + 26 END IF MID$(bevan$, tt, 1) = CHR$(x%) NEXT tt decoded$ = bevan$ PRINT "SpecialEdition : "; decoded$ END nincsn: PRINT "Packed file name : "; ax$ PRINT "Packed on date : "; dt$ IF crc$ = "Y" THEN crc$ = "Present!" PRINT "CRC+ Recovery : "; crc$ PRINT "Packed size :"; size&; "bytes" END END IF END SUB