DEFLNG A-Z DIM Char(1 TO 3) CONST NONE = 0, NM = 1, EXT = 2, ALL = 3 CONST TRUE = -1 CONST FALSE = NOT TRUE 'Display help. IF COMMAND$ = "" OR INSTR(COMMAND$, "/?") <> 0 THEN PRINT "GOBX.EXE - Dark Forces GOB extraction utility. Version 2.0. FREEWARE" PRINT " Copyright Stanislav Sokolov, April 1996." PRINT PRINT "Usage: GOBX FileName.GOB [Output location] [Mask|Mask.*|*.Mask]" PRINT " or: GOBX FileName.GOB /List" PRINT PRINT "Parameters must be entered in this specific order! If you specify Mask, then" PRINT "Output location MUST also be secified. Mask is NOT a wildcard: 'test.*' can" PRINT "both be 'testbase.*' and 'mytest.*'!" PRINT PRINT "/List produces a listing of the GOB's content. Output can be redirected to a" PRINT "file. No extractions are made if /List parameter is used." PRINT PRINT "Example 1: GOBX SOUNDS.GOB C:\MUSIC\ jan" PRINT "Extract all files containing 'jan' from SOUNDS.GOB to C:\MUSIC\" PRINT PRINT "Example 2: GOBX SPRITES.GOB C:\WAXES *.wax" PRINT "Extract all files with extention 'wax' from SPRITES.GOB to C:\WAXES\" PRINT PRINT "Example 3: GOBX DARK.GOB . secbase.*" PRINT "Extract all files containing 'secbase' in filename from DARK.GOB to current dir." END END IF 'Parse Command-line. p = INSTR(COMMAND$, " ") 'Get Dir IF p <> 0 THEN m = INSTR(p + 1, COMMAND$, " ") IF m <> 0 THEN Dir$ = LTRIM$(MID$(COMMAND$, p, m - p)) 'Get Mask Mask$ = LTRIM$(RIGHT$(COMMAND$, LEN(COMMAND$) - m)) ELSE Dir$ = LTRIM$(MID$(COMMAND$, p)) END IF IF RIGHT$(Dir$, 1) <> "\" THEN Dir$ = Dir$ + "\" ELSE p = LEN(COMMAND$) END IF 'Get FileName file$ = RTRIM$(LEFT$(COMMAND$, p)) 'Prepare Mask ToMask = NONE IF Mask$ <> "" THEN IF LEFT$(Mask$, 2) = "*." THEN Mask$ = MID$(Mask$, 3) ToMask = EXT ELSEIF RIGHT$(Mask$, 2) = ".*" THEN Mask$ = MID$(Mask$, 1, LEN(Mask$) - 2) ToMask = NM ELSE ToMask = ALL END IF END IF IF INSTR(COMMAND$, "/LIST") <> 0 THEN ToList = TRUE CLS LOCATE 6, 1 IF NOT ToList THEN PRINT "Press 'Esc' to abort." ELSE PRINT "Content of " + file$ PRINT END IF OPEN file$ FOR INPUT AS #1: CLOSE #1 OPEN file$ FOR BINARY AS #1 Text$ = " " Part$ = SPACE$(10000) FFile$ = SPACE$(12) Counter = 0 SizeCounter = 0 'Get the pointer to the address block (in the end of GOB-file) FOR a = 5 TO 7 GET #1, a, Text$ IF Text$ <> "" THEN Char(a - 4) = ASC(Text$) ELSE Char(a - 4) = 0 END IF Pointer = Pointer + 1 NEXT a Pointer = Char(1) + (Char(2) * 256) + (Char(3) * 256 ^ 2) + 5 DO 'Starting at the first entry in the address block, find out... '...the address of a file (stored in FPos), ... FOR a = 1 TO 3 GET #1, Pointer, Text$ IF Text$ <> "" THEN Char(a) = ASC(Text$) ELSE Char(a) = 0 END IF Pointer = Pointer + 1 NEXT a Pointer = Pointer + 1 FPos = Char(1) + (Char(2) * 256) + (Char(3) * 256 ^ 2) '... file's length (stored in FLen), ... FOR a = 1 TO 3 GET #1, Pointer, Text$ IF Text$ <> "" THEN Char(a) = ASC(Text$) ELSE Char(a) = 0 END IF Pointer = Pointer + 1 NEXT a Pointer = Pointer + 1 FLen = Char(1) + (Char(2) * 256) + (Char(3) * 256 ^ 2) '... and filename (stored in FName$). GET #1, Pointer, FFile$ FFile$ = UCASE$(FFile$) 'Validate file's name (store in N$) N$ = "" FOR a = 1 TO 12 F$ = MID$(FFile$, a, 1) IF F$ = "" OR F$ = "." THEN EXIT FOR IF ASC(F$) = 0 THEN EXIT FOR N$ = N$ + F$ NEXT a 'Validate file's extention (store in E$) E$ = "" FOR b = a TO 12 F$ = MID$(FFile$, b, 1) IF F$ = "" THEN EXIT FOR IF ASC(F$) = 0 THEN EXIT FOR E$ = E$ + F$ NEXT b 'File's name might be longer than 8, truncate it to 8.3 convention IF LEN(N$) > 8 THEN N$ = LEFT$(N$, 8) E$ = E$ + "!" END IF 'Put filename together FF$ = N$ + E$ 'Jump to next address in address block. Pointer = Pointer + 13 IF ToList THEN 'List GOB contents PRINT FF$ + SPACE$(15 - LEN(FF$)) + SPACE$(8 - LEN(STR$(FLen))) + STR$(FLen) + " bytes" Counter = Counter + 1 SizeCounter = SizeCounter + FLen ELSE LOCATE 3, 1 PRINT "Working with file: " + FF$ + SPACE$(15) 'Check Mask Allow = FALSE IF ToMask = NONE THEN Allow = TRUE ELSEIF ToMask = NM THEN IF INSTR(N$, Mask$) <> 0 THEN Allow = TRUE ELSEIF ToMask = EXT THEN IF INSTR(E$, Mask$) <> 0 THEN Allow = TRUE ELSEIF ToMask = ALL THEN IF INSTR(FF$, Mask$) <> 0 THEN Allow = TRUE END IF 'Copy the file from GOB to directory. IF Allow THEN OPEN Dir$ + FF$ FOR OUTPUT AS #2: CLOSE #2 OPEN Dir$ + FF$ FOR BINARY AS #2 NowLen = 0 FOR a = FPos + 1 TO FPos + FLen STEP 10000 LOCATE 1, 1 PRINT "Working at location:" + STR$(a) + SPACE$(15) GET #1, a, Part$ NowLen = NowLen + 10000 IF NowLen > FLen THEN Txt$ = LEFT$(Part$, 10000 - (NowLen - FLen)) PUT #2, , Txt$ EXIT FOR ELSE Txt$ = Part$ PUT #2, , Txt$ END IF NEXT a CLOSE #2 Counter = Counter + 1 SizeCounter = SizeCounter + FLen END IF END IF 'Check if the address block Pointer passed the last entry... LOOP UNTIL Pointer >= LOF(1) - 3 OR INKEY$ = CHR$(27) IF NOT ToList THEN LOCATE 7, 1 PRINT PRINT " Processed"; SizeCounter; "bytes in"; Counter; "files." END