home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Classic / MultimediaClassic.mdf / utility / vts139b.arj / VTCFG.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-12-22  |  14.2 KB  |  477 lines

  1. {****************************************************************************}
  2. {                                                                            }
  3. { MODULE:         VTCfg                                                      }
  4. {                                                                            }
  5. { DESCRIPTION:    Implements the reading of the VT.CFG configuration file.   }
  6. {                                                                            }
  7. { AUTHOR:         Juan Carlos ArĂ©valo                                        }
  8. {                                                                            }
  9. { MODIFICATIONS:  Nobody (yet ;-)                                            }
  10. {                                                                            }
  11. { HISTORY:        17-Oct-1992 Documentation                                  }
  12. {                                                                            }
  13. { (C) 1992 VangeliSTeam                                                      }
  14. {____________________________________________________________________________}
  15.  
  16. UNIT VTCfg;
  17.  
  18. {$I-}
  19.  
  20. INTERFACE
  21.  
  22. USES Dos,
  23.      VTGlobal,
  24.      PlayMod, ModCommands, SongElements,
  25.      SoundDevices, DevSpkr, DevSB, DevDAC, GUS,
  26.      Vid43, SoundBlaster, SwapStream;
  27.  
  28.  
  29.  
  30.  
  31. PROCEDURE ReadConfiguration(FName: PathStr); { Read and interpretate the file as a configuration file. }
  32.  
  33.  
  34.  
  35.  
  36. IMPLEMENTATION
  37.  
  38.  
  39. VAR
  40.   ConfFile : TEXT;   { Open configuration file.      }
  41.   Line     : STRING; { Last line read from the file. }
  42.  
  43.  
  44.  
  45.  
  46. {----------------------------------------------------------------------------}
  47. { Miscelaneous string handling routines.                                     }
  48. {____________________________________________________________________________}
  49.  
  50.  
  51. { KillSpaces. Deletes the blanks from the beginning and end of the string. }
  52.  
  53. PROCEDURE KillSpaces(VAR s: STRING);
  54.   CONST
  55.     ValidBlanks = [' ', #9, #0, #255];
  56.   BEGIN
  57.     WHILE (Length(s) > 0) AND (s[1]         IN ValidBlanks) DO
  58.       s := COPY(s, 2, 255);
  59.     WHILE (Length(s) > 0) AND (s[Length(s)] IN ValidBlanks) DO
  60.       DEC(s[0]);
  61.   END;
  62.  
  63.  
  64. { NotInStr. Returns TRUE if the first parameter doesn't contain the second
  65.             at the beginning.                                              }
  66.  
  67. FUNCTION NotInStr(s, ss: STRING) : BOOLEAN;
  68.   VAR
  69.     i : WORD;
  70.   BEGIN
  71.     NotInStr := TRUE;
  72.     IF Length(ss) > Length(s) THEN EXIT;
  73.     FOR i := 1 TO Length(ss) DO
  74.       IF UpCase(s[i]) <> UpCase(ss[i]) THEN EXIT;
  75.     NotInStr := FALSE;
  76.   END;
  77.  
  78.  
  79.  
  80.  
  81. {----------------------------------------------------------------------------}
  82. { Routines for reading different data types They all assume that 'Line'      }
  83. { contains a string in the format "<Identifier> = <value>".                  }
  84. { Their names ar self-explicative.                                           }
  85. {____________________________________________________________________________}
  86.  
  87.  
  88. FUNCTION GetString(VAR st: STRING; ml: WORD) : BOOLEAN;
  89.   VAR
  90.     s     : STRING;
  91.     s1    : STRING;
  92.     i, j,
  93.     k, l  : LONGINT;
  94.   BEGIN
  95.     i := Pos('=', Line) + 1;
  96.  
  97.     s := Copy(Line, i, 255);
  98.     KillSpaces(s);
  99.  
  100.     s1 := '';
  101.     WHILE Length(s) > 0 DO
  102.         IF s[1] = '''' THEN
  103.           BEGIN
  104.             s  := Copy(s, 2, 255);
  105.             i  := Pos('''', s);
  106.             IF i = 0 THEN i := 254;
  107.             s1 := s1 + Copy(s, 1, i-1);
  108.             IF (Length(s) > i) AND (s[i+1] = '''') THEN
  109.               s1 := s1 + '''';
  110.             s := Copy(s, i+1, 255);
  111.             IF Pos('''', s) = 0 THEN s := '';
  112.           END
  113.         ELSE
  114.           BEGIN
  115.             j := Pos(';', s);
  116.             k := Pos(':', s); IF (k <> 0) AND (j > k) THEN j := k;
  117.             k := Pos('#', s); IF (k <> 0) AND (j > k) THEN j := k;
  118.                                  IF  j =  0           THEN j := Length(s) + 1;
  119.             s1 := Copy(s, 1, j-1);
  120.             KillSpaces(s1);
  121.             s := ''
  122.           END;
  123.  
  124.     IF Length(s1) > ml THEN s1[0] := CHAR(ml);
  125.     st := s1;
  126.     GetString := TRUE;
  127.   END;
  128.  
  129.  
  130. FUNCTION GetBool(VAR b: BOOLEAN) : BOOLEAN;
  131.   VAR
  132.     s       : STRING;
  133.   BEGIN
  134.     GetBool := FALSE;
  135.     IF NOT GetString(s, SIZEOF(s) - 1) THEN EXIT;
  136.     IF (NOT NotInStr(s, 'S'    )) OR
  137.        (NOT NotInStr(s, 'Y'    )) OR
  138.        (NOT NotInStr(s, 'OUI'  )) OR
  139.        (NOT NotInStr(s, 'DA'   )) OR
  140.        (NOT NotInStr(s, 'POR'  )) OR
  141.        (NOT NotInStr(s, 'TAMB' )) OR
  142.        (NOT NotInStr(s, 'ALSO' )) OR
  143.        (NOT NotInStr(s, 'TRUE' )) OR
  144.        (NOT NotInStr(s, 'VERD' )) OR
  145.        (NOT NotInStr(s, 'CIER' )) OR
  146.        (NOT NotInStr(s, '1'    )) THEN
  147.       BEGIN
  148.         b       := TRUE;
  149.         GetBool := TRUE;
  150.       END
  151.     ELSE IF (NOT NotInStr(s, 'N'     )) OR
  152.             (NOT NotInStr(s, 'PAS'   )) OR
  153.             (NOT NotInStr(s, 'TAMP'  )) OR
  154.             (NOT NotInStr(s, 'FALS'  )) OR
  155.             (NOT NotInStr(s, '0'     )) THEN
  156.       BEGIN
  157.         b       := FALSE;
  158.         GetBool := TRUE;
  159.       END;
  160.   END;
  161.  
  162.  
  163. FUNCTION GetPath(VAR p: PathStr) : BOOLEAN;
  164.   BEGIN
  165.     GetPath := FALSE;
  166.     IF NOT GetString(p, SIZEOF(p) - 1) THEN EXIT;
  167.     p := FExpand(p);
  168.     GetPath := TRUE;
  169.   END;
  170.  
  171.  
  172. FUNCTION GetNum(VAR b: LONGINT) : BOOLEAN;
  173.   TYPE
  174.     LP = ^LONGINT;
  175.   VAR
  176.     s       : STRING;
  177.     i, j, k : LONGINT;
  178.   BEGIN
  179.     i := Pos('=', Line) + 1;
  180.     j := Pos(';', Line);
  181.     k := Pos(':', Line); IF (k <> 0) AND (j > k) THEN j := k;
  182.     k := Pos('#', Line); IF (k <> 0) AND (j > k) THEN j := k;
  183.                          IF               j = 0  THEN j := Length(Line) + 1;
  184.     s := Copy(Line, i, j-i);
  185.     KillSpaces(s);
  186.  
  187.     j := 1;
  188.  
  189.     IF (Length(s) > 3) AND (s[1] = '[') THEN
  190.       BEGIN
  191.         j := Pos(']', s);
  192.         IF j <> 0 THEN
  193.           BEGIN
  194.             VAL(Copy(s, 2, j-2), i, WORD(j));
  195.             IF j = 0 THEN
  196.               i := LP(Ptr((i AND $F0000) SHR 4, i AND $FFFF))^;
  197.           END
  198.         ELSE
  199.           j := 1;
  200.       END
  201.     ELSE
  202.       VAL(s, i, WORD(j));
  203.  
  204.     IF j <> 0 THEN
  205.       BEGIN
  206.         GetNum := FALSE;
  207.         EXIT;
  208.       END;
  209.     b := i;
  210.     GetNum := TRUE;
  211.   END;
  212.  
  213.  
  214. FUNCTION GetWord(VAR b: WORD) : BOOLEAN;
  215.   VAR
  216.     l : LONGINT;
  217.   BEGIN
  218.     IF GetNum(l) THEN
  219.       BEGIN
  220.         b := WORD(l);
  221.         GetWord := TRUE;
  222.       END
  223.     ELSE
  224.       GetWord := FALSE;
  225.   END;
  226.  
  227.  
  228. FUNCTION GetByte(VAR b: BYTE) : BOOLEAN;
  229.   VAR
  230.     l : LONGINT;
  231.   BEGIN
  232.     IF GetNum(l) THEN
  233.       BEGIN
  234.         b := BYTE(l);
  235.         GetByte := TRUE;
  236.       END
  237.     ELSE
  238.       GetByte := FALSE;
  239.   END;
  240.  
  241.  
  242.  
  243.  
  244. {----------------------------------------------------------------------------}
  245. { Routines that implement the actual interpretation of the identifiers.      }
  246. { One routine for each section.                                              }
  247. {____________________________________________________________________________}
  248.  
  249. TYPE
  250.   Proc = PROCEDURE;
  251.  
  252.  
  253. { DoSectSB. [VT-SBlaster] (Sound Blaster) section. }
  254.  
  255. PROCEDURE DoSectSB; FAR;
  256.   BEGIN
  257.     IF NOT NotInStr(Line, 'IRQ'         ) THEN GetWord(SbIrq);
  258.     IF NOT NotInStr(Line, 'Port'        ) THEN GetWord(SbPort);
  259.     IF NOT NotInStr(Line, 'DMA'         ) THEN GetWord(SbDMAChan);
  260.     IF NOT NotInStr(Line, 'SbSplTimeout') THEN GetWord(SbSplTimeout);
  261.     IF NOT NotInStr(Line, 'HiSpeedDMA'  ) THEN GetBool(SbHiSpeed);
  262.   END;
  263.  
  264.  
  265. { DoSectGUS. [VT-GUS] (Ultrasound) section. }
  266.  
  267. PROCEDURE DoSectGUS; FAR;
  268.   BEGIN
  269.     IF NOT NotInStr(Line, 'Port'        ) THEN GetWord(GUSPort);
  270.     IF NOT NotInStr(Line, 'IRQ'         ) THEN GetWord(GUSIrq);
  271.   END;
  272.  
  273.  
  274. { DoSectSBPro. [VT-SBPro] (Sound Blaster Pro) section. }
  275.  
  276. PROCEDURE DoSectSBPro; FAR;
  277.   BEGIN
  278.     IF NOT NotInStr(Line, 'MasterVol'   ) THEN GetByte(SbProMixMasterVol);
  279.     IF NOT NotInStr(Line, 'DACVol'      ) THEN GetByte(SbProMixDACVol);
  280.     IF NOT NotInStr(Line, 'FMVol'       ) THEN GetByte(SbProMixFMVol);
  281.     IF NOT NotInStr(Line, 'Filter'      ) THEN GetBool(SbProMixFilter);
  282.   END;
  283.  
  284.  
  285. { DoSectDAC. [VT-DAC] section. }
  286.  
  287. PROCEDURE DoSectDAC; FAR;
  288.   BEGIN
  289.     IF NOT NotInStr(Line, 'Port' ) THEN GetWord(DACPort);
  290.     IF NOT NotInStr(Line, 'LPort') THEN GetWord(LDACPort);
  291.     IF NOT NotInStr(Line, 'RPort') THEN GetWord(RDACPort);
  292.   END;
  293.  
  294.  
  295. { DoSectPlayMod. [VT-PlayMod] section }
  296.  
  297. PROCEDURE DoSectPlayMod; FAR;
  298.   BEGIN
  299.     IF NOT NotInStr(Line, 'PermitFade'  ) THEN GetBool(PermitFade);
  300.     IF NOT NotInStr(Line, 'FadeSpeed'   ) THEN GetWord(FadeIncr);
  301.     IF NOT NotInStr(Line, 'LoopMod'     ) THEN GetBool(VTLoopMod);
  302.     IF NOT NotInStr(Line, 'ForceLoopMod') THEN GetBool(ForceLoopMod);
  303.     IF NOT NotInStr(Line, 'ShellLoopMod') THEN GetBool(ShellLoopMod);
  304.     IF NOT NotInStr(Line, 'SampleFreq'  ) THEN GetWord(DesiredHz);
  305.     IF NOT NotInStr(Line, 'TicksPerSec' ) THEN GetWord(TicksPerSecond);
  306.     IF NOT NotInStr(Line, 'ShellFreq'   ) THEN GetWord(ShellHz);
  307.     IF NOT NotInStr(Line, 'MaxFreq'     ) THEN GetWord(MaxOutputFreq);
  308.     IF NOT NotInStr(Line, 'Volume'      ) THEN GetByte(VtVolume);
  309.     IF NOT NotInStr(Line, 'Device'      ) THEN GetString(DevID, SIZEOF(DevID) - 1);
  310.     IF NOT NotInStr(Line, 'FilterOn'    ) THEN GetByte(BYTE(FilterOn));
  311.     IF NOT NotInStr(Line, 'FilterOff'   ) THEN GetByte(BYTE(FilterOff));
  312.     IF NOT NotInStr(Line, 'FilterIsOn'  ) THEN GetBool(FilterIsOn);
  313.     IF NOT NotInStr(Line, 'CanFallBack' ) THEN GetBool(CanFallBack);
  314.     IF NOT NotInStr(Line, 'FilterChange') THEN GetBool(PermitFilterChange);
  315.     IF NOT NotInStr(Line, 'BassFilter'  ) THEN GetBool(DoBassPower);
  316.     IF NOT NotInStr(Line, 'DMAOffset'   ) THEN GetWord(DMAOffset);
  317.     IF NOT NotInStr(Line, 'LowQuality'  ) THEN GetBool(LowQuality);
  318.     IF NOT NotInStr(Line, 'Volume'      ) THEN GetByte(VtVolume);
  319.   END;
  320.  
  321.  
  322. { DoSectDAC. [VT-Misc] section. }
  323.  
  324. PROCEDURE DoSectMisc; FAR;
  325.   BEGIN
  326.     IF NOT NotInStr(Line, 'ShellPath'  ) THEN GetPath  (ShellPath);
  327.     IF NOT NotInStr(Line, 'ShellParams') THEN GetString(ShellParam,   SIZEOF(ShellParam)   - 1);
  328.     IF NOT NotInStr(Line, 'Language')    THEN GetPath  (StringsFName);
  329.     IF NOT NotInStr(Line, 'ModPath')     THEN GetPath  (ModPath);
  330.     IF NOT NotInStr(Line, 'TmpPath')     THEN GetPath  (SwapPrimPath);
  331.   END;
  332.  
  333.  
  334. { DoSectDAC. [VT-Screen] section. }
  335.  
  336. PROCEDURE DoSectScreen; FAR;
  337.   BEGIN
  338.     IF NOT NotInStr(Line, 'ForceEGA') THEN GetBool(ForceEGA);
  339.   END;
  340.  
  341.  
  342. { DoSectGeneric. Generic section interpreter. It calls one of the above. }
  343.  
  344. PROCEDURE DoSectGeneric(Offs: WORD); FAR;
  345.   VAR
  346.     DoSect : POINTER;
  347.   BEGIN
  348.     DoSect := Ptr(SEG(DoSectGeneric), Offs);
  349.     WHILE NOT EoF(ConfFile) DO
  350.       BEGIN
  351.         ReadLn(ConfFile, Line);
  352.         KillSpaces(Line);
  353.         IF (Length(Line) > 0) THEN
  354.           BEGIN
  355.             IF (Line[1] = '[') THEN EXIT;
  356.             IF (Line[1] <> ';') AND
  357.                (Line[1] <> ':') AND
  358.                (Line[1] <> '#') THEN
  359.               ASM
  360.  
  361.                         CALL    [DoSect];
  362.               END;
  363.           END;
  364.       END;
  365.   END;
  366.  
  367.  
  368. { Sections definitions. }
  369.  
  370. TYPE
  371.   SectProc = PROCEDURE;
  372.  
  373. CONST
  374.   NumSects = 7;                                 { Number of controlled sections. }
  375.   SectList : ARRAY[1..NumSects] OF RECORD       { List of controlled sections.   }
  376.                                     Proc : WORD;
  377.                                     Name : STRING[16];
  378.                                   END =  
  379.     ( ( Proc:OFS(DoSectSB);      Name:'[VT-SBlaster]' ) ,
  380.       ( Proc:OFS(DoSectGUS);     Name:'[VT-GUS]'      ) ,
  381.       ( Proc:OFS(DoSectSBPro);   Name:'[VT-SBPro]'    ) ,
  382.       ( Proc:OFS(DoSectPlayMod); Name:'[VT-PlayMod]'  ) ,
  383.       ( Proc:OFS(DoSectDAC);     Name:'[VT-DAC]'      ) ,
  384.       ( Proc:OFS(DoSectMisc);    Name:'[VT-Misc]'     ) ,
  385.       ( Proc:OFS(DoSectScreen);  Name:'[VT-Screen]'   )
  386.     );
  387.  
  388.  
  389.  
  390.  
  391. {----------------------------------------------------------------------------}
  392. { Configuration reader's main loop.                                          }
  393. {____________________________________________________________________________}
  394.  
  395.  
  396. { FindNextSect. Skips until the beginning of the next section. }
  397.  
  398. PROCEDURE FindNextSect;
  399.   BEGIN
  400.     WHILE NOT EoF(ConfFile) DO
  401.       BEGIN
  402.         ReadLn(ConfFile, Line);
  403.         KillSpaces(Line);
  404.         IF (Length(Line) > 0) AND (Line[1] = '[') THEN EXIT;
  405.       END;
  406.   END;
  407.  
  408.  
  409. { ReadConfiguration. Configuration reader. Main loop. }
  410.  
  411. PROCEDURE ReadConfiguration(FName: PathStr);
  412.   VAR
  413.     i    : WORD;
  414.     Good : BOOLEAN;
  415.   BEGIN
  416.     Assign(ConfFIle, FName);
  417.     i := FileMode;
  418.     FileMode := 0;
  419.     Reset(ConfFile);
  420.     FileMode := i;
  421.     IF IOResult <> 0 THEN EXIT;
  422.  
  423.     WHILE NOT EoF(ConfFile) DO
  424.       BEGIN
  425.         FindNextSect;
  426.         Good := TRUE;
  427.         WHILE (Good)              AND
  428.               (NOT EoF(ConfFile)) AND
  429.               (Length(Line) <> 0) AND
  430.               (Line[1] = '[')     DO
  431.           BEGIN
  432.             Good := FALSE;
  433.             FOR i := 1 TO NumSects DO
  434.               IF NOT NotInStr(SectList[i].Name, Line) THEN
  435.                 BEGIN
  436.                   DoSectGeneric(SectList[i].Proc);
  437.                   Good := TRUE;
  438.                 END;
  439.           END;
  440.       END;
  441.  
  442.     Close(ConfFile);
  443.   END;
  444.  
  445.  
  446.  
  447.  
  448. {----------------------------------------------------------------------------}
  449. { Unit initialization code. It reads two configuration files:                }
  450. {   1st. - A file named like the executable, but with the extension .CFG, in }
  451. {          the same directory as the executable.                             }
  452. {   2nd. - A file named VT.CFG in the current directory.                     }
  453. {                                                                            }
  454. { The changes read from the second file may overwrite those read from the    }
  455. { first.                                                                     }
  456. {____________________________________________________________________________}
  457.  
  458. VAR
  459.   Path : PathStr;
  460.   Name : NameStr;
  461.   Ext  : ExtStr;
  462.  
  463. BEGIN
  464.  
  465.   Path := ParamStr(0);          { Executable's full pathname. }
  466.   FSplit(Path, VTDir, Name, Ext);
  467.   IF Name <> 'VT' THEN
  468.     BEGIN
  469.       ReadConfiguration(VTDir+'VT.CFG');
  470.       ReadConfiguration('VT.CFG');
  471.     END;
  472.  
  473.   ReadConfiguration(VTDir+Name+'.CFG');
  474.   ReadConfiguration(Name+'.CFG');
  475.  
  476. END.
  477.