// MDXWin Constructor

unit _MDXWinINI;

interface

uses
  Forms,SysUtils,Types, INIFiles,
  _PicTools, _const, _SndDrv_const;

type
  TListFontINI=record
    Name:string;
    Size:integer;
  end;

type
  TMainINI=record
    SetupLastPage:integer;
    SplashScreen:boolean;
    MainPriorityLevel:integer;
    CatalogFilePath:string;
    DropActiveWindow:boolean;
    VisibleTrayIcon:boolean;
    ToolTipTransparentLevel:integer;
    SKIFilename:string;
    PlayMode:integer;
    MainPos:TWindowPos; // Default WindowLocation
    TotalVolume:LongInt; // min 0 < Normal 1024 < over...
    LoopMax:LongInt; // フェードアウトループ回数
    UseRomeo:boolean;
    UseDSound:integer;
    UseSRCMode:integer;
    DSoundSafeTime:LongInt; // DirectSound Prebuffer(ms)
    DSoundRate:dword; // PCMRate_?????
    WAO_DLLName:string;
    MDXOnlineTimeoutSec:integer;
    MDXOnlineBufferSize:integer;
    MDXOnlineAutoUpdate:boolean;
    CompactWindowEnabled:boolean;
    CompactWindowFlortEnabled:boolean;
    CompactWindowFlortDockMain:boolean;
    CompactWindowFlortPos:TWindowPos; // Default WindowLocation
    TitleFontName:string;
    TitleUseESC:boolean;
    TitleUseAnk2to1byte:boolean;
    WaveLocalPath:string; // ローカルファイル時のWaveMP3書き出しフォルダ
    WaveLocalEqualMDXFolder:boolean; // 書き出しフォルダ False=WaveLocalPathへ True=MDXと同じフォルダへ
    WaveNetworkPath:string; // MDXOnline時のWaveMP3書き出しフォルダ
    DefPath:string; // 曲データ初期フォルダ
    CurrentFilePath:string;
    CurrentPath:array[0..DriveMax] of string;
    UserPath:array[0..9] of string;
    WADSPEnabled:boolean;
    WADSPRegInit:boolean;
    NetFindPos:TWindowPos; // Default WindowLocation
    NetFindFile,NetFindTitle1,NetFindTitle2:string;
    NetFind_PlayStop:boolean;
    NetFind_AutoFind:integer;
    NetFind_EnableHomeEndKey:boolean;
    NetRankPos:TWindowPos; // Default WindowLocation
    NetRankRankMode:integer;
    NetRankMaxCountIndex:integer;
    NetVotePos:TWindowPos;
    NetVoteMaxCountIndex:integer;
    NetVoteView2lineComment:boolean;
    NetVoteViewFontName:string;
    NetVoteViewFontSize:integer;
    NetVoteLastName:string;
    NetVoteLastRating:byte;
    NetVoteLastCelebrity:byte;
    NetVoteLastGenre:byte;
    KDDPos:TWindowPos; // Default WindowLocation
    UseKDD:boolean;
    KDDAntialias:boolean;
    KDDTextFont:string;
    WavesPos:TWindowPos;
    WavesLastMPPFilename:string;
    NetRemoteEnabled:boolean;
    NetRemotePort:integer;
    NetRemoteLoginPassword:string;
    NetRemoteLocalOnly:boolean;
  end;

type
  TVisINI=record
    SetupLastPage:integer;
    UseEffect:boolean;
    GradEnabled:boolean;
    AlreadyRefresh:boolean; // 非アクティブでもイメージを更新する。
    AnalyzeFrame:LongInt; // 画面描画の秒間フレーム数（制限有り）
    AnalyzeFFT:LongInt; // 画面描画に対してFFTを計算するフレーム数
    VisualMode:LongInt;
    SpeanaMode:LongInt;
    KeyboardUseFadeout:boolean;
    KeyboardDraw9to16trk:boolean;
    KeyboardRealKeys:boolean;
    Effect3DRot:integer;
    Effect3DRotAuto:boolean;
    Effect3DFullScreen:boolean;
    Effect3DDDBlurMode:integer;
    SpeanaWaveAntialias:boolean;
    SpeanaWaveZeroAjust:boolean;
    SpeanaBarDoubleSide:boolean;
    SpeanaLineAntialias:boolean;
    SonarAntialias:boolean;
    SonarBaseColor:dword;
    SonarBaseColorMorph:byte;
  end;

type
  TMXDRVgINI=record
    Enabled:boolean;
    MDXBufMax,PDXBufMax:integer;
    usePCM8:boolean;
  end;

type
  TMXDRVmINI=record
    PDXFilePath:string;
    MarcuryVolume:LongInt; // MarcuryUnit Volume min 0 < Normal 1024 < over...
    ADPCMSRCMode:integer;
  end;

type
  TFMPMDINI=record
    PCMFMPPMDPath:array[0..PCMFMPPMDPathCount] of string; // for FMP,PMD
    PCMYM2608Path:string; // for FMP,PMD
    DLLProgressLoad:boolean;
    FMCalc55k:boolean;
    Interpolation:boolean;
    LoadInitADPCM:boolean;
    PPSUse:boolean;
    RhythmWithSSGEffect:boolean;
    ADPCMPPZ8Emulate:boolean;
    PMD86PCMMode:boolean;
    VolFM:integer;
    VolSSG:integer;
    VolRhythm:integer;
    VolADPCM:integer;
    VolPPZ:integer;
  end;

type
  TSPCINI=record
    EnabledWinAMPDSP:boolean;
    MixMode:dword; // ref _SNESAPU_Moonlight.pas
    IntMode:dword;
    DSPOpt_LowpassFilter:boolean;
    DSPOpt_OldADPCMDecompress:boolean;
    DSPOpt_SurroundSound:boolean;
    DSPOpt_ReverseStereo:boolean;
    DSPPitch:dword;
    EnabledID666Length:boolean;
    DefaultSongLenSec:dword;
    DefaultFadeoutLenSec:dword;
  end;

type
  TOutAsioINI=record
    DriverIndex:integer;
    LeftCh,RightCh:integer;
    LatencyBuffer:integer;
  end;

var
  ListFontINI:TListFontINI;
  MainINI:TMainINI;
  VisINI:TVisINI;
  MXDRVmINI:TMXDRVmINI;
  MXDRVgINI:TMXDRVgINI;
  FMPMDINI:TFMPMDINI;
  SPCINI:TSPCINI;
  OutAsioINI:TOutAsioINI;

procedure MDXWinINIFileload(fn:string);
procedure MDXWinINIFilesave(fn:string);

implementation

uses _m_Tools, _SimpleDialog, _MDXWin_const, _Vis_const, _SNESAPU_Moonlight;

procedure MDXWinINIFileload(fn:string);
var
  MainINIFileExist:boolean;
  AppINI:TMemIniFile;
  cnt:integer;
  Section:string;
  StartDir:string;
  DesktopDir,DesktopPath:string;
  tmpdrv:string;
begin
  StartDir:=ExtractFileDir(Application.ExeName)+'\';
  DesktopDir:=GetDesktopPath;
  DesktopPath:=DesktopDir+'\';

  if FileExists(fn)=False then begin
    AppINI:=TMemIniFile.Create(fn);
    end else begin
    AppINI:=TMemIniFile.Create(fn);

    MainINIFileExist:=True;

    if AppINI.ReadString('SystemConfig', 'ID', 'null')<>'MDXWin' then begin
      MainINIFileExist:=False;
    end;
    if AppINI.ReadString('SystemConfig', 'Version', 'null')<>'1.10' then begin
      ShowMessage('MDXWin.exe','古いバージョン用のMDXWin.iniを削除しました。'+chr(13)+'環境設定が初期化されています。'+chr(13)+'再設定してください。');
      MainINIFileExist:=False;
    end;

    if MainINIFileExist=False then begin
      AppINI.Free;
      DeleteFile(fn);
      AppINI:=TMemIniFile.Create(fn);
    end;
  end;

  with MainINI do begin
    Section:='SystemConfig';
    SetupLastPage:=AppINI.ReadInteger(Section, 'SetupLastPage', 0);
    SplashScreen:=AppINI.ReadBool(Section, 'SplashScreen', True);
    MainPriorityLevel:=AppINI.ReadInteger(Section, 'MainPriorityLevel', 4);
    CatalogFilePath:=AppINI.ReadString(Section, 'CatalogFilePath', StartDir+'Catalog');
    PlayMode:=AppINI.ReadInteger(Section, 'PlayMode', PlayMode_ALL);
    DropActiveWindow:=AppINI.ReadBool(Section, 'DropActiveWindow', False);
    VisibleTrayIcon:=AppINI.ReadBool(Section, 'VisibleTrayIcon', True);
    VisibleTrayIcon:=True;
    SKIFilename:=AppINI.ReadString(Section, 'SKIFilename', '');
    if FileExists(SKIFilename)=False then SKIFilename:=StartPath+'MDXWin.ski';
    ToolTipTransparentLevel:=AppINI.ReadInteger(Section, 'ToolTipTransparentLevel', 255);
    TotalVolume:=AppINI.ReadInteger(Section, 'TotalVolume', 1024);
    LoopMax:=AppINI.ReadInteger(Section, 'LoopMax', 2);
    UseRomeo:=AppINI.ReadBool(Section, 'UseRomeo', False);
    UseDSound:=AppINI.ReadInteger(Section, 'UseDSound', PCMOut_DirectSound);
    UseSRCMode:=AppINI.ReadInteger(Section, 'UseSRCMode', SRCMode_Liner);
    DSoundSafeTime:=AppINI.ReadInteger(Section, 'DSoundSafeTime', 200);
    DSoundRate:=AppINI.ReadInteger(Section, 'DSoundRate', PCMRate_44kHz);
    WAO_DLLName:=AppINI.ReadString(Section, 'WAO_DLLName', '');
    MDXOnlineTimeoutSec:=AppINI.ReadInteger(Section, 'MDXOnlineTimeoutSec', 5);
    if MDXOnlineTimeoutSec=15 then MDXOnlineTimeoutSec:=5;
    MDXOnlineBufferSize:=AppINI.ReadInteger(Section, 'MDXOnlineBufferSize', 8192);
    MDXOnlineAutoUpdate:=AppINI.ReadBool(Section, 'MDXOnlineAutoUpdate', True);

    Section:='CompactWindow';
    CompactWindowEnabled:=AppINI.ReadBool(Section, 'Enabled', False);
    CompactWindowFlortEnabled:=AppINI.ReadBool(Section, 'FlortEnabled', True);
    CompactWindowFlortDockMain:=AppINI.ReadBool(Section, 'FlortDockMain', True);
    with CompactWindowFlortPos do begin
      Left:=AppINI.ReadInteger(Section,'FlortPosLeft',MainPos.Left+8);
      Top:=AppINI.ReadInteger(Section,'FlortPosTop',MainPos.Top+64);
      Width:=AppINI.ReadInteger(Section,'FlortPosWidth',640);
      Height:=AppINI.ReadInteger(Section,'FlortPosHeight',400);
    end;

    Section:='TitleText';
    TitleFontName:=AppINI.ReadString(Section,'FontName','ＭＳ 明朝');
    TitleUseESC:=AppINI.ReadBool(Section,'UseESC',True);
    TitleUseAnk2to1byte:=AppINI.ReadBool(Section,'UseAnk2to1byte',True);

    Section:='CurrentPath';

    CurrentFilePath:=AppINI.ReadString(Section, 'drv', DesktopPath);
    if CurrentFilePath='' then CurrentFilePath:=DesktopPath;
    tmpdrv:=CurrentFilePath[1];
    if (tmpdrv<>'#') and ((tmpdrv<'0') or ('9'<tmpdrv)) then begin
      if DirectoryExists(CurrentFilePath)=False then CurrentFilePath:=DesktopPath;
    end;

    for cnt:=0 to DriveMax-1 do begin
      CurrentPath[cnt]:=AppINI.ReadString(Section, 'drv'+copy(DriveName,cnt+1,1), '');
    end;

    Section:='UserPath';
    for cnt:=0 to 9 do begin
      UserPath[cnt]:=AppINI.ReadString(Section, 'drv'+inttostr(cnt), '');
      if UserPath[cnt]<>'' then begin
        if copy(UserPath[cnt],length(UserPath[cnt]),1)<>'\' then UserPath[cnt]:=UserPath[cnt]+'\';
      end;
    end;

    Section:='DefaultLocation';
    with MainPos do begin
      Left:=AppINI.ReadInteger(Section,'Left',Left);
      Top:=AppINI.ReadInteger(Section,'Top',Top);
      Width:=AppINI.ReadInteger(Section,'Width',Width);
      Height:=AppINI.ReadInteger(Section,'Height',Height);
    end;

    if DirectoryExists(CatalogFilePath)=False then CatalogFilePath:=StartDir+'Catalog';

    Section:='ExtendConvert';
    WaveLocalPath:=AppINI.ReadString(Section, 'WaveLocalPath', DesktopDir);
    WaveLocalEqualMDXFolder:=AppINI.ReadBool(Section,'WaveLocalEqualMDXFolder',False);
    WaveNetworkPath:=AppINI.ReadString(Section, 'WaveNetworkPath', DesktopDir);

    if DirectoryExists(WaveLocalPath)=False then WaveLocalPath:=DesktopDir;
    if DirectoryExists(WaveNetworkPath)=False then WaveNetworkPath:=DesktopDir;

    DefPath:=AppINI.ReadString(Section, 'DefPath', DesktopDir);
    if DirectoryExists(DefPath)=False then DefPath:=DesktopDir;

    Section:='WinAMPDSPPlugin';
    WADSPEnabled:=AppINI.ReadBool(Section,'Enabled',True);
    WADSPRegInit:=AppINI.ReadBool(Section,'RegInit',False);

    Section:='NetFind';
    with NetFindPos do begin
      Left:=AppINI.ReadInteger(Section,'PosLeft',MainPos.Left+8);
      Top:=AppINI.ReadInteger(Section,'PosTop',MainPos.Top+64);
      Width:=AppINI.ReadInteger(Section,'PosWidth',640);
      Height:=AppINI.ReadInteger(Section,'PosHeight',400);
    end;
    NetFindFile:=AppINI.ReadString(Section,'File','');
    NetFindTitle1:=AppINI.ReadString(Section,'Title1','');
    NetFindTitle2:=AppINI.ReadString(Section,'Title2','');
    NetFind_PlayStop:=AppINI.ReadBool(Section,'PlayStop',True);
    NetFind_AutoFind:=AppINI.ReadInteger(Section,'AutoFind',1);
    NetFind_EnableHomeEndKey:=AppINI.ReadBool(Section,'EnableHomeEndKey',False);

    Section:='NetRank';
    with NetRankPos do begin
      Left:=AppINI.ReadInteger(Section,'PosLeft',MainPos.Left+8);
      Top:=AppINI.ReadInteger(Section,'PosTop',MainPos.Top+128);
      Width:=AppINI.ReadInteger(Section,'PosWidth',640);
      Height:=AppINI.ReadInteger(Section,'PosHeight',400);
    end;
    NetRankRankMode:=AppINI.ReadInteger(Section,'RankMode',0);
    NetRankMaxCountIndex:=AppINI.ReadInteger(Section,'MaxCountIndex',0);

    Section:='NetVote';
    with NetVotePos do begin
      Left:=AppINI.ReadInteger(Section,'PosLeft',MainPos.Left+8);
      Top:=AppINI.ReadInteger(Section,'PosTop',MainPos.Top+128);
      Width:=AppINI.ReadInteger(Section,'PosWidth',640);
      Height:=AppINI.ReadInteger(Section,'PosHeight',400);
    end;
    NetVoteMaxCountIndex:=AppINI.ReadInteger(Section,'MaxCountIndex',0);
    NetVoteView2lineComment:=AppINI.ReadBool(Section,'View2lineComment',True);
    NetVoteViewFontName:=AppINI.ReadString(Section,'Name','Terminal');
    NetVoteViewFontSize:=AppINI.ReadInteger(Section,'Size',10);
    NetVoteLastName:=AppINI.ReadString(Section,'LastName','');
    NetVoteLastRating:=byte(AppINI.ReadInteger(Section,'NetVoteLastRating',0));
    NetVoteLastCelebrity:=byte(AppINI.ReadInteger(Section,'NetVoteLastCelebrity',0));
    NetVoteLastGenre:=byte(AppINI.ReadInteger(Section,'NetVoteLastGenre',0));

    Section:='KDD';
    with KDDPos do begin
      Left:=AppINI.ReadInteger(Section,'PosLeft',MainPos.Left+8);
      Top:=AppINI.ReadInteger(Section,'PosTop',MainPos.Top+32);
      Width:=AppINI.ReadInteger(Section,'PosWidth',0);
      Height:=AppINI.ReadInteger(Section,'PosHeight',0);
    end;
    UseKDD:=AppINI.ReadBool(Section,'UseKDD',True);
    KDDAntialias:=AppINI.ReadBool(Section,'KDDAntialias',True);
    KDDTextFont:=AppINI.ReadString(Section,'KDDTextFont','ＭＳ 明朝');

    Section:='WavesOut';
    with WavesPos do begin
      Left:=AppINI.ReadInteger(Section,'PosLeft',MainPos.Left+8);
      Top:=AppINI.ReadInteger(Section,'PosTop',MainPos.Top-100);
      Width:=AppINI.ReadInteger(Section,'PosWidth',640);
      Height:=AppINI.ReadInteger(Section,'PosHeight',200);
    end;
    WavesLastMPPFilename:=AppINI.ReadString(Section,'LastMPPFilename',DesktopDir+'\notitle.mpp');

    Section:='NetRemote';
    NetRemoteEnabled:=AppINI.ReadBool(Section,'Enabled',False);
    NetRemotePort:=AppINI.ReadInteger(Section,'Port',12280);
    NetRemoteLoginPassword:=AppINI.ReadString(Section,'LoginPassword','');
    NetRemoteLocalOnly:=AppINI.ReadBool(Section,'LocalOnly',True);
  end;

  with ListFontINI do begin
    Section:='ListFont';
    Name:=AppINI.ReadString(Section,'Name','ＭＳ ゴシック');
    Size:=AppINI.ReadInteger(Section,'Size',10);
  end;

  with VisINI do begin
    Section:='VisGlobal';
    SetupLastPage:=AppINI.ReadInteger(Section, 'SetupLastPage', 0);
    UseEffect:=AppINI.ReadBool(Section, 'EffectUse', True);
    GradEnabled:=AppINI.ReadBool(Section, 'GradEnabled', True);
    AlreadyRefresh:=AppINI.ReadBool(Section,'AlreadyRefresh',False);
    VisualMode:=AppINI.ReadInteger(Section,'VisualMode',VisualModeKeyboard);
    SpeanaMode:=AppINI.ReadInteger(Section,'SpeanaMode',SpeanaModeLine);
    AnalyzeFrame:=AppINI.ReadInteger(Section,'AnalyzeFrame',30);
    AnalyzeFFT:=AppINI.ReadInteger(Section,'AnalyzeFFT',1);
    Effect3DRot:=AppINI.ReadInteger(Section,'Effect3DRot',trunc((random(2000)-1000)*PI*2));
    Effect3DRotAuto:=AppINI.ReadBool(Section,'Effect3DRotAuto',True);
    Effect3DFullScreen:=AppINI.ReadBool(Section,'Effect3DFullScreen',False);
    Effect3DDDBlurMode:=AppINI.ReadInteger(Section,'Effect3DDDBlurModeReduction',DDBlurModeReduction);

    Section:='VisKeyboard';
    KeyboardUseFadeout:=AppINI.ReadBool(Section,'UseFadeout',True);
    KeyboardDraw9to16trk:=AppINI.ReadBool(Section,'Draw9to16trk',False);
    KeyboardRealKeys:=AppINI.ReadBool(Section,'RealKeys',False);
    Section:='VisSpeana';
    SpeanaWaveAntialias:=AppINI.ReadBool(Section,'WaveAntialias',True);
    SpeanaWaveZeroAjust:=AppINI.ReadBool(Section,'WaveZeroAjust',True);
    SpeanaBarDoubleSide:=AppINI.ReadBool(Section,'BarDoubleSide',True);
    SpeanaLineAntialias:=AppINI.ReadBool(Section,'LineAntialias',True);
    Section:='VisSonar';
    SonarAntialias:=AppINI.ReadBool(Section,'Antialias',True);
    SonarBaseColor:=AppINI.ReadInteger(Section,'BaseColor',$c0c0ff);
    SonarBaseColorMorph:=AppINI.ReadInteger(Section,'BaseColorMorph',$40);
  end;

  with MXDRVmINI do begin
    Section:='MXDRVm';
    PDXFilePath:=AppINI.ReadString(Section, 'PDXFilePath', StartDir+'MXDRV_PDX');
    MarcuryVolume:=AppINI.ReadInteger(Section, 'MarcuryVolume', 1024);
    ADPCMSRCMode:=AppINI.ReadInteger(Section, 'ADPCMSRCMode', 0);
    if DirectoryExists(PDXFilePath)=False then PDXFilePath:=StartDir+'MXDRV_PDX';
  end;

  with MXDRVgINI do begin
    Section:='MXDRVg';
    Enabled:=AppINI.ReadBool(Section, 'Enabled', False);
    MDXBufMax:=AppINI.ReadInteger(Section, 'MDXBufMax', 512*1024);
    PDXBufMax:=AppINI.ReadInteger(Section, 'PDXBufMax', 2048*1024);
    usePCM8:=AppINI.ReadBool(Section, 'usePCM8', True);
  end;

  with FMPMDINI do begin
    Section:='FMPPMD';
    PCMYM2608Path:=AppINI.ReadString(Section, 'PCMYM2608Path', StartDir+'YM2608_Rhythm');
    for cnt:=0 to PCMFMPPMDPathCount-1 do
      PCMFMPPMDPath[cnt]:=AppINI.ReadString(Section, 'PCMFMPPMDPath'+IntToStr(cnt),'');

    if DirectoryExists(PCMYM2608Path)=False then PCMYM2608Path:=StartDir+'YM2608_Rhythm';
    if DirectoryExists(PCMFMPPMDPath[0])=False then PCMFMPPMDPath[0]:=StartDir+'FMPPMD_PCM';

    DLLProgressLoad:=AppINI.ReadBool(Section,'DLLProgressLoad',True);
    FMCalc55k:=AppINI.ReadBool(Section,'FMCalc55k',True);
    Interpolation:=AppINI.ReadBool(Section,'Interpolation',True);
    LoadInitADPCM:=AppINI.ReadBool(Section,'LoadInitADPCM',False);

    PPSUse:=AppINI.ReadBool(Section,'PPSUse',True);
    RhythmWithSSGEffect:=AppINI.ReadBool(Section,'RhythmWithSSGEffect',False);
    ADPCMPPZ8Emulate:=AppINI.ReadBool(Section,'ADPCMPPZ8Emulate',False);
    PMD86PCMMode:=AppINI.ReadBool(Section,'PMD86PCMMode',False);

    VolFM:=AppINI.ReadInteger(Section,'VolFM',0);
    VolSSG:=AppINI.ReadInteger(Section,'VolSSG',0);
    VolRhythm:=AppINI.ReadInteger(Section,'VolRhythm',0);
    VolADPCM:=AppINI.ReadInteger(Section,'VolADPCM',0);
    VolPPZ:=AppINI.ReadInteger(Section,'VolPPZ',0);
  end;

  Section:='SPC';
  with SPCINI do begin
    EnabledWinAMPDSP:=AppINI.ReadBool(Section,'EnabledWinAMPDSP',True);
    MixMode:=AppINI.ReadInteger(Section,'MixMode',MIX_MMX);
    IntMode:=AppINI.ReadInteger(Section,'IntMode',INT_GAUSS);
    DSPOpt_LowpassFilter:=AppINI.ReadBool(Section,'DSPOpt_LowpassFilter',True);
    DSPOpt_OldADPCMDecompress:=AppINI.ReadBool(Section,'DSPOpt_OldADPCMDecompress',False);
    DSPOpt_SurroundSound:=AppINI.ReadBool(Section,'DSPOpt_SurroundSound',False);
    DSPOpt_ReverseStereo:=AppINI.ReadBool(Section,'DSPOpt_ReverseStereo',False);
    DSPPitch:=AppINI.ReadInteger(Section,'DSPPitch',DSPPitch_Normal);
    EnabledID666Length:=AppINI.ReadBool(Section,'EnabledID666Length',True);
    DefaultSongLenSec:=AppINI.ReadInteger(Section,'DefaultSongLenSec',90);
    DefaultFadeoutLenSec:=AppINI.ReadInteger(Section,'DefaultFadeoutLenSec',5);
  end;

  Section:='OutAsio';
  with OutAsioINI do begin
    DriverIndex:=AppINI.ReadInteger(Section,'DriverIndex',0);
    LeftCh:=AppINI.ReadInteger(Section,'LeftCh',0);
    RightCh:=AppINI.ReadInteger(Section,'RightCh',1);
    LatencyBuffer:=AppINI.ReadInteger(Section,'LatencyBuffer',1024);
  end;

  AppINI.Free;
end;

procedure MDXWinINIFilesave(fn:string);
var
  AppINI:TextFile;
  cnt:integer;
  Section,LastSection:string;
  procedure WriteValue(Ident:string;Value:string);
  begin
    if LastSection<>Section then begin
      LastSection:=Section;
      Writeln(AppINI,'['+Section+']');
    end;
    Writeln(AppINI,Ident+'='+Value);
  end;
  procedure WriteString(Ident:string;Value:string);
  begin
    WriteValue(Ident,Value);
  end;
  procedure WriteInteger(Ident:string;Value:integer);
  begin
    WriteValue(Ident,inttostr(Value));
  end;
  procedure WriteBool(Ident:string;Value:boolean);
  begin
    if Value=True then begin
      WriteValue(Ident,'1');
      end else begin
      WriteValue(Ident,'0');
    end;
  end;
begin
  LastSection:='';

  DeleteFile(fn);
  AssignFile(AppINI,fn);
  Rewrite(AppINI);

  Section:='SystemConfig';
  WriteString('ID', 'MDXWin');
  WriteString('Version', '1.10');
  WriteString('Current', MDXWinCurrent);

  with MainINI do begin
    WriteInteger('SetupLastPage', SetupLastPage);
    WriteString('CatalogFilePath', CatalogFilePath);
    WriteBool('SplashScreen', SplashScreen);
    WriteInteger('MainPriorityLevel', MainPriorityLevel);
    WriteInteger('PlayMode', PlayMode);
    WriteBool('DropActiveWindow', DropActiveWindow);
    WriteBool('VisibleTrayIcon', VisibleTrayIcon);
    WriteInteger('ToolTipTransparentLevel', ToolTipTransparentLevel);
    WriteString('SKIFilename', SKIFilename);
    WriteInteger('TotalVolume', TotalVolume);
    WriteInteger('LoopMax', LoopMax);
    WriteBool('UseRomeo', UseRomeo);
    WriteInteger('UseDSound', UseDSound);
    WriteInteger('UseSRCMode', UseSRCMode);
    WriteInteger('DSoundSafeTime', DSoundSafeTime);
    WriteInteger('DSoundRate', DSoundRate);
    WriteString('WAO_DLLName', WAO_DLLName);
    WriteInteger('MDXOnlineTimeoutSec', MDXOnlineTimeoutSec);
    WriteInteger('MDXOnlineBufferSize', MDXOnlineBufferSize);
    WriteBool('MDXOnlineAutoUpdate', MDXOnlineAutoUpdate);

    Section:='CompactWindow';
    WriteBool('Enabled', CompactWindowEnabled);
    WriteBool('FlortEnabled', CompactWindowFlortEnabled);
    WriteBool('FlortDockMain', CompactWindowFlortDockMain);
    with CompactWindowFlortPos do begin
      WriteInteger('FlortPosLeft',Left);
      WriteInteger('FlortPosTop',Top);
      WriteInteger('FlortPosWidth',Width);
      WriteInteger('FlortPosHeight',Height);
    end;

    Section:='TitleText';
    WriteString('FontName',TitleFontName);
    WriteBool('UseESC',TitleUseESC);
    WriteBool('UseAnk2to1byte',TitleUseAnk2to1byte);

    Section:='CurrentPath';
    WriteString('drv', CurrentFilePath);
    for cnt:=0 to DriveMax-1 do begin
      WriteString('drv'+copy(DriveName,cnt+1,1), CurrentPath[cnt]);
    end;

    Section:='UserPath';
    for cnt:=0 to 9 do begin
      WriteString('drv'+inttostr(cnt), UserPath[cnt]);
    end;

    Section:='ExtendConvert';
    WriteString('WaveLocalPath', WaveLocalPath);
    WriteBool('WaveLocalEqualMDXFolder',WaveLocalEqualMDXFolder);
    WriteString('WaveNetworkPath', WaveNetworkPath);
    WriteString('DefPath', DefPath);

    Section:='DefaultLocation';
    with MainPos do begin
      WriteInteger('Left', Left);
      WriteInteger('Top', Top);
      WriteInteger('Width', Width);
      WriteInteger('Height', Height);
    end;

    Section:='WinAMPDSPPlugin';
    WriteBool('Enabled',WADSPEnabled);
    WriteBool('RegInit',WADSPRegInit);

    Section:='NetFind';
    with NetFindPos do begin
      WriteInteger('PosLeft',Left);
      WriteInteger('PosTop',Top);
      WriteInteger('PosWidth',Width);
      WriteInteger('PosHeight',Height);
    end;
    WriteString('File',NetFindFile);
    WriteString('Title1',NetFindTitle1);
    WriteString('Title2',NetFindTitle2);
    WriteBool('PlayStop',NetFind_PlayStop);
    WriteInteger('AutoFind',NetFind_AutoFind);
    WriteBool('EnableHomeEndKey',NetFind_EnableHomeEndKey);

    Section:='NetRank';
    with NetRankPos do begin
      WriteInteger('PosLeft',Left);
      WriteInteger('PosTop',Top);
      WriteInteger('PosWidth',Width);
      WriteInteger('PosHeight',Height);
    end;
    WriteInteger('RankMode',NetRankRankMode);
    WriteInteger('MaxCountIndex',NetRankMaxCountIndex);

    Section:='NetVote';
    with NetVotePos do begin
      WriteInteger('PosLeft',Left);
      WriteInteger('PosTop',Top);
      WriteInteger('PosWidth',Width);
      WriteInteger('PosHeight',Height);
    end;
    WriteInteger('MaxCountIndex',NetVoteMaxCountIndex);
    WriteBool('View2lineComment',NetVoteView2lineComment);
    WriteString('Name',NetVoteViewFontName);
    WriteInteger('Size',NetVoteViewFontSize);
    WriteString('LastName',NetVoteLastName);
    WriteInteger('NetVoteLastRating',NetVoteLastRating);
    WriteInteger('NetVoteLastCelebrity',NetVoteLastCelebrity);
    WriteInteger('NetVoteLastGenre',NetVoteLastGenre);

    Section:='KDD';
    with KDDPos do begin
      WriteInteger('PosLeft',Left);
      WriteInteger('PosTop',Top);
      WriteInteger('PosWidth',Width);
      WriteInteger('PosHeight',Height);
    end;
    WriteBool('UseKDD',UseKDD);
    WriteBool('KDDAntialias',KDDAntialias);
    WriteString('KDDTextFont',KDDTextFont);

    Section:='WavesOut';
    with WavesPos do begin
      WriteInteger('PosLeft',Left);
      WriteInteger('PosTop',Top);
      WriteInteger('PosWidth',Width);
      WriteInteger('PosHeight',Height);
    end;
    WriteString('LastMPPFilename',WavesLastMPPFilename);

    Section:='NetRemote';
    WriteBool('Enabled',NetRemoteEnabled);
    WriteInteger('Port',NetRemotePort);
    WriteString('LoginPassword',NetRemoteLoginPassword);
    WriteBool('LocalOnly',NetRemoteLocalOnly);
  end;

  with ListFontINI do begin
    Section:='ListFont';
    WriteString('Name', Name);
    WriteInteger('Size', Size);
  end;

  with VisINI do begin
    Section:='VisGlobal';
    WriteInteger('SetupLastPage', SetupLastPage);
    WriteBool('EffectUse', UseEffect);
    WriteBool('GradEnabled', GradEnabled);
    WriteBool('AlreadyRefresh',AlreadyRefresh);
    WriteInteger('VisualMode', VisualMode);
    WriteInteger('SpeanaMode', SpeanaMode);
    WriteInteger('AnalyzeFrame',AnalyzeFrame);
    WriteInteger('AnalyzeFFT',AnalyzeFFT);
    WriteInteger('Effect3DRot',Effect3DRot);
    WriteBool('Effect3DRotAuto',Effect3DRotAuto);
    WriteBool('Effect3DFullScreen',Effect3DFullScreen);
    WriteInteger('Effect3DDDBlurModeReduction',Effect3DDDBlurMode);

    Section:='VisKeyboard';
    WriteBool('UseFadeout',KeyboardUseFadeout);
    WriteBool('Draw9to16trk',KeyboardDraw9to16trk);
    WriteBool('RealKeys',KeyboardRealKeys);

    Section:='VisSpeana';
    WriteBool('WaveAntialias',SpeanaWaveAntialias);
    WriteBool('WaveZeroAjust',SpeanaWaveZeroAjust);
    WriteBool('BarDoubleSide',SpeanaBarDoubleSide);
    WriteBool('LineAntialias',SpeanaLineAntialias);

    Section:='VisSonar';
    WriteBool('Antialias',SonarAntialias);
    WriteInteger('BaseColor',SonarBaseColor);
    WriteInteger('BaseColorMorph',SonarBaseColorMorph);
  end;

  with MXDRVmINI do begin
    Section:='MXDRVm';
    WriteString('PDXFilePath', PDXFilePath);
    WriteInteger('MarcuryVolume', MarcuryVolume);
    WriteInteger('ADPCMSRCMode', ADPCMSRCMode);
  end;

  with MXDRVgINI do begin
    Section:='MXDRVg';
    WriteBool('Enabled', Enabled);
    WriteInteger('MDXBufMax', MDXBufMax);
    WriteInteger('PDXBufMax', PDXBufMax);
    WriteBool('usePCM8', usePCM8);
  end;

  with FMPMDINI do begin
    Section:='FMPPMD';
    WriteString('PCMYM2608Path', PCMYM2608Path);
    for cnt:=0 to PCMFMPPMDPathCount-1 do
      WriteString('PCMFMPPMDPath'+IntToStr(cnt),PCMFMPPMDPath[cnt]);

    WriteBool('DLLProgressLoad',DLLProgressLoad);
    WriteBool('FMCalc55k',FMCalc55k);
    WriteBool('Interpolation',Interpolation);
    WriteBool('LoadInitADPCM',LoadInitADPCM);

    WriteBool('PPSUse',PPSUse);
    WriteBool('RhythmWithSSGEffect',RhythmWithSSGEffect);
    WriteBool('ADPCMPPZ8Emulate',ADPCMPPZ8Emulate);
    WriteBool('PMD86PCMMode',PMD86PCMMode);

    WriteInteger('VolFM',VolFM);
    WriteInteger('VolSSG',VolSSG);
    WriteInteger('VolRhythm',VolRhythm);
    WriteInteger('VolADPCM',VolADPCM);
    WriteInteger('VolPPZ',VolPPZ);
  end;

  with SPCINI do begin
    Section:='SPC';
    WriteBool('EnabledWinAMPDSP',EnabledWinAMPDSP);
    WriteInteger('MixMode',MixMode);
    WriteInteger('IntMode',IntMode);
    WriteBool('DSPOpt_LowpassFilter',DSPOpt_LowpassFilter);
    WriteBool('DSPOpt_OldADPCMDecompress',DSPOpt_OldADPCMDecompress);
    WriteBool('DSPOpt_SurroundSound',DSPOpt_SurroundSound);
    WriteBool('DSPOpt_ReverseStereo',DSPOpt_ReverseStereo);
    WriteInteger('DSPPitch',DSPPitch);
    WriteBool('EnabledID666Length',EnabledID666Length);
    WriteInteger('DefaultSongLenSec',DefaultSongLenSec);
    WriteInteger('DefaultFadeoutLenSec',DefaultFadeoutLenSec);
  end;

  with OutAsioINI do begin
    Section:='OutAsio';
    WriteInteger('DriverIndex',DriverIndex);
    WriteInteger('LeftCh',LeftCh);
    WriteInteger('RightCh',RightCh);
    WriteInteger('LatencyBuffer',LatencyBuffer);
  end;

  CloseFile(AppINI);
end;

end.

