unit frmMenuunt;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  frmDebuggerUnt, Profile, IntvControls, StdCtrls, ExtCtrls,
  Grids, ComCtrls, Base;

Const
  ConfigFile     = 'INTVWIN.INI';
  CRLF           = #13 + #10;

type
// ------------------------------------------------------

  TInitSound     = Procedure;
  TSoundBuf      = Packed Array[0..1] Of Pointer;

// ------------------------------------------------------
  TfrmMenu = class(TForm)
    sbMain: TStatusBar;
    sgMain: TStringGrid;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure sgMainDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure sgMainDblClick(Sender: TObject);
    procedure sgMainMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure sgMainClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    Cols     : Integer;
    Rows     : Integer;
    FileList : TList;
//    Procedure MainMenuHelp;
    Procedure LoadStringGrid;
  public
    { Public declarations }
    Procedure SaveConfiguration(Var Config: ConfigRec; Version: String);
    Procedure ProcessChosenCart(Ch: Char; Item: TFileListItem);
    Procedure InitConfig(Var Config: ConfigRec; Version: String);
  end;

var
  frmMenu : TfrmMenu;

implementation

{$R *.DFM}

Uses INIFiles,HexWrite,ProtMenu,frmInfoUnt, frmMainunt, frmAltMenuUnt, ZipMstr;

Const
  DisplayColWidth: Array[TDisplayScheme] Of Byte = (16,15,14,12,11,10,40,40);

Procedure TfrmMenu.InitConfig(Var Config: ConfigRec; Version: String);
Var
  F   : TINIFile;
  St  : String;
  W,H : Integer;
  I   : Integer;

Begin
  Config.DoSound            := True;
  Config.FrameRate          := 60;
  Config.ScreenModeWidth    := 80;
  Config.ScreenModeHeight   := 25;
  Config.ScreenModeDepth    := 1;
  Config.MenuColorScheme    := csGameType;
  Config.MenuForeColor1     := clBlack;
  Config.MenuForeColor2     := clBlack;
  Config.MenuBackColor1     := clSilver;
  Config.MenuBackColor2     := clWhite;
  Config.HideAllOnZoomFull  := False;
  Config.ShowFPS            := False;
  Config.GamePath           := '';
  Config.ScreenShotPath     := '';
  Config.BoxFrontScanPath   := '';
  Config.BoxBackScanPath    := '';
  Config.BoxSideScanPath    := '';
  Config.CartScanPath       := '';
  Config.OverlayScanPath    := '';
  Config.ManualPath         := '';
{
  Config.MenuForeColor1     := LightGray;
  Config.MenuForeColor2     := White;
  Config.MenuBackColor1     := Blue;
  Config.MenuBackColor2     := Blue;
}
  Config.MenuDisplayScheme  := dsNameExt4;

  { Initalize controller interfaces }

  InterfaceHandler.AddInterface(TMouseInterface.Create);
  InterfaceHandler.AddInterface(TKeyboardInterface.Create);
  InterfaceHandler.AddInterface(TDigitalInterface.Create('Digital'));
  InterfaceHandler.AddInterface(TExternalInterface.Create);
//  InterfaceHandler.AddInterface(New(PJoystickInterface,Init));
//  InterfaceHandler.AddInterface(New(PGrIPInterface,Init));
//  InterfaceHandler.AddInterface(New(PSideWinderInterface,Init));
{  InterfaceHandler.AddInterface(New(PLogitechInterface,Init));}
//  InterfaceHandler.AddInterface(New(PExternalInterface,Init));

//  If FileExists(ExtractFilePath(Application.ExeName) + ConfigFile) Then
//  Begin
    F := TINIFile.Create(ExtractFilePath(Application.ExeName) + ConfigFile);
    Config.DoSound           := F.ReadBool('GENERAL','DOSOUND',False);
    Config.FrameRate         := F.ReadInteger('GENERAL','FRAMERATE',60);
    Config.ScreenModeWidth   := F.ReadInteger('GENERAL','SCREENMODEWIDTH',80);
    Config.ScreenModeHeight  := F.ReadInteger('GENERAL','SCREENMODEHEIGHT',25);
    Config.ScreenModeDepth   := F.ReadInteger('GENERAL','SCREENMODEDEPTH',8);
    Config.MenuColorScheme   := TColorScheme(F.ReadInteger('GENERAL','MENUCOLORSCHEME',LongInt(csGameType)));
    Config.MenuForeColor1    := F.ReadInteger('GENERAL','MENUFORECOLOR1',clBlack);
    Config.MenuForeColor2    := F.ReadInteger('GENERAL','MENUFORECOLOR2',clBlack);
    Config.MenuBackColor1    := F.ReadInteger('GENERAL','MENUBACKCOLOR1',clSilver);
    Config.MenuBackColor2    := F.ReadInteger('GENERAL','MENUBACKCOLOR2',clWhite);
    Config.MenuDisplayScheme := TDisplayScheme(F.ReadInteger('GENERAL','MENUDISPLAYSCHEME',LongInt(dsNameExt4)));
    Config.GamePath          := F.ReadString('GENERAL','GAMEPATH',ExtractFilePath(Application.EXEName));
    Config.ScreenShotPath    := F.ReadString('GENERAL','SHOTPATH',ExtractFilePath(Application.EXEName));
    Config.BoxFrontScanPath  := F.ReadString('GENERAL','BOXFRONTSCANPATH',ExtractFilePath(Application.EXEName));
    Config.BoxBackScanPath   := F.ReadString('GENERAL','BOXBACKSCANPATH',ExtractFilePath(Application.EXEName));
    Config.BoxSideScanPath   := F.ReadString('GENERAL','BOXSIDESCANPATH',ExtractFilePath(Application.EXEName));
    Config.CartScanPath      := F.ReadString('GENERAL','CARTSCANPATH',ExtractFilePath(Application.EXEName));
    Config.OverlayScanPath   := F.ReadString('GENERAL','OVERLAYSCANPATH',ExtractFilePath(Application.EXEName));
    Config.ManualPath        := F.ReadString('GENERAL','MANUALPATH',ExtractFilePath(Application.EXEName));
    Config.Exec              := F.ReadString('GENERAL','EXEC','EXEC.BIN');
    Config.ECS               := F.ReadString('GENERAL','ECS','ECS.BIN');
    Config.GROM              := F.ReadString('GENERAL','GROM','GROM.BIN');
    Config.KBDC              := F.ReadString('GENERAL','KBDC','KBDC.BIN');
    Config.KBDAlpha          := F.ReadString('GENERAL','KBDALPHA','KBDALPHA.BIN');
    Config.ROM6502           := F.ReadString('GENERAL','ROM6502','6502.BIN');
    Config.IVoiceROM         := F.ReadString('GENERAL','IVOICEROM','IVOICE.BIN');
    Config.HideAllOnZoomFull := F.ReadBool('GENERAL','HIDEALLONZOOMFULL',False);
    Config.ShowFPS           := F.ReadBool('GENERAL','SHOWFPS',False);
    Config.ZoomMode          := F.ReadInteger('GENERAL','ZOOMMODE',1);
    FontName                 := F.ReadString('GENERAL','FONTNAME',FontName);
    FontSize                 := F.ReadInteger('GENERAL','FONTSIZE',FontSize);
    Font.Name                := F.ReadString('GENERAL','MENUFONTNAME',Font.Name);
    Font.Size                := F.ReadInteger('GENERAL','MENUFONTSIZE',Font.Size);
    frmAltMenu.Font.Name     := Font.Name;
    frmAltMenu.Font.Size     := Font.Size;
    St                       := UpperCase(F.ReadString('GENERAL','MENUFONTSTYLE',''));
    Font.Style := [];
    If Pos('B',St) <> 0 Then Font.Style := Font.Style + [fsBold];
    If Pos('I',St) <> 0 Then Font.Style := Font.Style + [fsItalic];
    If Pos('U',St) <> 0 Then Font.Style := Font.Style + [fsUnderline];
    If Pos('S',St) <> 0 Then Font.Style := Font.Style + [fsStrikeout];
    frmAltMenu.Font.Style := Font.Style;
    If frmMain.UseDirectDraw Then frmMain.DDFullScreen := F.ReadBool('GENERAL','FULLSCREEN',False);
    If frmMain.UseDirectDraw Then frmMain.TVScreen     := F.ReadBool('GENERAL','TVSCREEN',False);
    WindowState := wsNormal;
    W := F.ReadInteger('GENERAL','MENUWIDTH',Width);
    H := F.ReadInteger('GENERAL','MENUHEIGHT',Height);
    If (W > 200) And (W <= Screen.Width)  Then Width  := W;
    If (H > 200) And (H <= Screen.Height) Then Height := H;
    W := F.ReadInteger('GENERAL','ALTMENUWIDTH',Width);
    H := F.ReadInteger('GENERAL','ALTMENUHEIGHT',Height);
    If (W > 200) And (W <= Screen.Width)  Then frmAltMenu.Width  := W;
    If (H > 200) And (H <= Screen.Height) Then frmAltMenu.Height := H;
    If F.ReadBool('GENERAL','MENUMAXIMIZED',(WindowState = wsMaximized)) Then WindowState := wsMaximized;
    If F.ReadBool('GENERAL','ALTMENUMAXIMIZED',(frmAltMenu.WindowState = wsMaximized)) Then frmAltMenu.WindowState := wsMaximized;
    Config.AlternateGameMenu := F.ReadBool('GENERAL','ALTGAMEMENU',False);
    For I := 0 To 4 Do
    Begin
      W := F.ReadInteger('GENERAL','ALTMENUWIDTH' + IntToStr(I),frmAltMenu.sgMain.ColWidths[I]);
      If W < 4 Then W := 4;
      If W <= frmAltMenu.sgMain.Width Then frmAltMenu.sgMain.ColWidths[I] := W;
    End; // For I
    frmAltMenu.Sort    := TMenuSort(F.ReadInteger('GENERAL','ALTMENUSORT',Integer(frmAltMenu.Sort)));
    frmAltMenu.SortAsc := F.ReadBool('GENERAL','ALTMENUSORTASC',frmAltMenu.SortAsc);

    { Load controller interface information }

    InterfaceHandler.LoadConfiguration(F);
    F.Free;
//  End
//  Else SaveConfiguration(Config,Version);
End; { TfrmMenu.InitConfig }

Procedure TfrmMenu.SaveConfiguration(Var Config: ConfigRec; Version: String);
Var
  F  : TINIFile;
  St : String;
  I  : Integer;

Begin
//  DeleteFile(ExtractFilePath(Application.ExeName) + ConfigFile);
  F := TINIFile.Create(ExtractFilePath(Application.ExeName) + ConfigFile);
  F.WriteBool('GENERAL','DOSOUND',Config.DoSound);
  F.WriteInteger('GENERAL','FRAMERATE',Config.FrameRate);
  F.WriteInteger('GENERAL','SCREENMODEWIDTH',Config.ScreenModeWidth);
  F.WriteInteger('GENERAL','SCREENMODEHEIGHT',Config.ScreenModeHeight);
  F.WriteInteger('GENERAL','SCREENMODEDEPTH',Config.ScreenModeDepth);
  F.WriteInteger('GENERAL','MENUCOLORSCHEME',LongInt(Config.MenuColorScheme));
  F.WriteInteger('GENERAL','MENUFORECOLOR1',Config.MenuForeColor1);
  F.WriteInteger('GENERAL','MENUFORECOLOR2',Config.MenuForeColor2);
  F.WriteInteger('GENERAL','MENUBACKCOLOR1',Config.MenuBackColor1);
  F.WriteInteger('GENERAL','MENUBACKCOLOR2',Config.MenuBackColor2);
  F.WriteInteger('GENERAL','MENUDISPLAYSCHEME',LongInt(Config.MenuDisplayScheme));
  F.WriteString('GENERAL','FONTNAME',FontName);
  F.WriteInteger('GENERAL','FONTSIZE',FontSize);
  F.WriteString('GENERAL','EXEC',Config.Exec);
  F.WriteString('GENERAL','ECS',Config.ECS);
  F.WriteString('GENERAL','GROM',Config.GROM);
  F.WriteString('GENERAL','KBDC',Config.KBDC);
  F.WriteString('GENERAL','KBDALPHA',Config.KBDAlpha);
  F.WriteString('GENERAL','ROM6502',Config.ROM6502);
  F.WriteString('GENERAL','IVOICEROM',Config.IVoiceROM);
  F.WriteString('GENERAL','MENUFONTNAME',Font.Name);
  F.WriteInteger('GENERAL','MENUFONTSIZE',Font.Size);
  St := '';
  If fsBold      In Font.Style Then St := St + 'B';
  If fsItalic    In Font.Style Then St := St + 'I';
  If fsUnderline In Font.Style Then St := St + 'U';
  If fsStrikeout In Font.Style Then St := St + 'S';
  F.WriteString('GENERAL','MENUFONTSTYLE',St);
  F.WriteBool('GENERAL','FULLSCREEN',frmMain.DDFullScreen);
  F.WriteBool('GENERAL','TVSCREEN',frmMain.TVScreen);
  F.WriteString('GENERAL','GAMEPATH',Config.GamePath);
  F.WriteString('GENERAL','SHOTPATH',Config.ScreenShotPath);
  F.WriteString('GENERAL','BOXFRONTSCANPATH',Config.BoxFrontScanPath);
  F.WriteString('GENERAL','BOXBACKSCANPATH',Config.BoxBackScanPath);
  F.WriteString('GENERAL','BOXSIDESCANPATH',Config.BoxSideScanPath);
  F.WriteString('GENERAL','CARTSCANPATH',Config.CartScanPath);
  F.WriteString('GENERAL','OVERLAYSCANPATH',Config.OverlayScanPath);
  F.WriteString('GENERAL','MANUALPATH',Config.ManualPath);
  If WindowState <> wsMaximized Then
  Begin
    F.WriteInteger('GENERAL','MENUWIDTH',Width);
    F.WriteInteger('GENERAL','MENUHEIGHT',Height);
  End;
  If frmAltMenu.WindowState <> wsMaximized Then
  Begin
    F.WriteInteger('GENERAL','ALTMENUWIDTH',frmAltMenu.Width);
    F.WriteInteger('GENERAL','ALTMENUHEIGHT',frmAltMenu.Height);
  End;
  F.WriteBool('GENERAL','MENUMAXIMIZED',(WindowState = wsMaximized));
  F.WriteBool('GENERAL','ALTMENUMAXIMIZED',(frmAltMenu.WindowState = wsMaximized));
  F.WriteBool('GENERAL','ALTGAMEMENU',Config.AlternateGameMenu);
  For I := 0 To 4 Do
   F.WriteInteger('GENERAL','ALTMENUWIDTH' + IntToStr(I),frmAltMenu.sgMain.ColWidths[I]);
  F.WriteInteger('GENERAL','ALTMENUSORT',Integer(frmAltMenu.Sort));
  F.WriteBool('GENERAL','ALTMENUSORTASC',frmAltMenu.SortAsc);
  F.WriteBool('GENERAL','HIDEALLONZOOMFULL',Config.HideAllOnZoomFull);
  F.WriteBool('GENERAL','SHOWFPS',Config.ShowFPS);
  F.WriteInteger('GENERAL','ZOOMMODE',Config.ZoomMode);
  InterfaceHandler.SaveConfiguration(F);
  F.UpdateFile;
  F.Free;
End; { TfrmMenu.SaveConfiguration }
(*
Procedure TfrmMenu.MainMenuHelp;
Begin
  Window.Screen.TextColor(LightGray);
  Window.Screen.TextBackGround(Blue);
  Window.Screen.ClrScr;
  Window.Screen.GotoXY(3,1);  Window.Screen.Write('Run options');

  Window.Screen.GotoXY(5,3);  Window.Screen.Write('<Esc> ............................ Quit');
  Window.Screen.GotoXY(5,4);  Window.Screen.Write('Arrow keys or Joystick ........... Move selection');
  Window.Screen.GotoXY(5,5);  Window.Screen.Write('<Enter> or Joystick button 1 ..... Run 2K/4K/Atari 8K/Atari 16K cart');
  Window.Screen.GotoXY(5,6);  Window.Screen.Write('A ................................ Run Activision 16K cart');
  Window.Screen.GotoXY(5,7);  Window.Screen.Write('M ................................ Run M-Network 8K RAM cart');
  Window.Screen.GotoXY(5,8);  Window.Screen.Write('P ................................ Run Parker Bros. 8K cart');
  Window.Screen.GotoXY(5,9);  Window.Screen.Write('R ................................ Run Atari super-chip cart');
  Window.Screen.GotoXY(5,10); Window.Screen.Write('T ................................ Run TigerVision cart');
  Window.Screen.GotoXY(5,11); Window.Screen.Write('2 ................................ Run Pitfall II cart');
  Window.Screen.GotoXY(3,13); Window.Screen.Write('Game options');
  Window.Screen.GotoXY(5,14); Window.Screen.Write('F1 ............................... Help/status screen');
  Window.Screen.GotoXY(5,15); Window.Screen.Write('F2 ............................... Reset game');
  Window.Screen.GotoXY(5,16); Window.Screen.Write('F3 ............................... Toggle NTSC/PAL palette');
  Window.Screen.GotoXY(5,17); Window.Screen.Write('F4 ............................... Select game');
  Window.Screen.GotoXY(5,18); Window.Screen.Write('F5 ............................... Color/BW switch');
  Window.Screen.GotoXY(5,19); Window.Screen.Write('F6/F7 ............................ Player 1/2 difficulty');
  Window.Screen.GotoXY(5,20); Window.Screen.Write('F8 ............................... Save game info to profile file');
  Window.Screen.GotoXY(5,21); Window.Screen.Write('F9 ............................... Capture screen to .BMP file');
  Window.Screen.GotoXY(5,22); Window.Screen.Write('F10 .............................. Toggle vertical autocentering');
  Window.Screen.GotoXY(5,23); Window.Screen.Write('F11 .............................. Save game to disk');
  Window.Screen.GotoXY(5,24); Window.Screen.Write('F12 .............................. Load saved game from disk');
  Window.Screen.GotoXY(5,25); Window.Screen.Write('=,- .............................. Shift screen up or down');
  Window.ReadKey;
  Window.Screen.TextColor(LightGray);
  Window.Screen.TextBackGround(Blue);
  Window.Screen.ClrScr;
End; { TfrmMenu.MainMenuHelp }
*)
procedure TfrmMenu.FormCreate(Sender: TObject);
begin
  MenuInfo.Title       := '';
  MenuInfo.FileName    := '';
  MenuInfo.ZipFileName := '';
  FileList             := TList.Create;
end;

procedure TfrmMenu.FormResize(Sender: TObject);
begin
  LoadStringGrid;
end; // TfrmMenu.FormResize

procedure TfrmMenu.FormShow(Sender: TObject);
Var
  S     : TSearchRec;
  Item  : TFileListItem;
  Item1 : TFileListItem;
  I,J   : Integer;
  St1   : String;
  St2   : String;
  Z     : ZipDirEntry;

begin
  Caption           := 'IntvWin ' + Version;
  Cols              := 1;
  Rows              := 1;
{
  MenuInfo.FileName := '';
  MenuInfo.Title    := '';
}
  // If there are any entries, get rid of them

  While FileList.Count > 0 Do
  Begin
    TFileListItem(FileList[0]).Free;
    FileList.Delete(0);
  End; // While

  If ParamCount > 0 Then Path := ParamStr(1) Else Path := Config.GamePath;
  If (Path <> '') And Not (Path[Length(Path)] In [':','\']) Then Path := Path + '\';

  // Locate all .BIN and .ROM files

  If FindFirst(Path + '*.BIN',faArchive,S) = 0 Then
  Repeat
    Item := TFileListItem.Create;
    FileList.Add(Item);
    Item.Name         := S.Name;
    Item.ZIPName      := '';
    Item.Size         := S.Size;
    Item.Prof         := Nil;
    Item.RNam         := '';
    Item.ScreenShot   := False;
    Item.BoxFrontScan := False;
    Item.BoxBackScan  := False;
    Item.BoxSideScan  := False;
    Item.CartScan     := False;
    Item.Manual       := False;
    Item.OverlayScan  := False;
    Item.Extras       := '';
    FindProfile(S.Name,Item.Prof);
    If (Item.Prof <> Nil) And (Item.Prof.RealName <> '')
     Then Item.RNam := Item.Prof.RealName
     Else Item.RNam := Item.Name;
  Until FindNext(S) <> 0;

  If FindFirst(Path + '*.ROM',faArchive,S) = 0 Then
  Repeat
    Item := TFileListItem.Create;
    FileList.Add(Item);
    Item.Name         := S.Name;
    Item.ZIPName      := '';
    Item.Size         := S.Size;
    Item.Prof         := Nil;
    Item.RNam         := '';
    Item.ScreenShot   := False;
    Item.BoxFrontScan := False;
    Item.BoxBackScan  := False;
    Item.BoxSideScan  := False;
    Item.CartScan     := False;
    Item.Manual       := False;
    Item.OverlayScan  := False;
    Item.Extras       := '';
    FindProfile(S.Name,Item.Prof);
    If (Item.Prof <> Nil) And (Item.Prof.RealName <> '')
     Then Item.RNam := Item.Prof.RealName
     Else Item.RNam := Item.Name;
  Until FindNext(S) <> 0;

  // Locate all .ZIP files, and locate all .BIN and .PAL files in those files

  If FindFirst(Path + '*.ZIP',faArchive,S) = 0 Then
  Repeat
    frmMain.ZipMaster1.ZipFilename := Path + S.Name;
    I := 0;
    While I < frmMain.ZipMaster1.ZipContents.Count Do
    Begin
      Z := PZipDirEntry(frmMain.ZipMaster1.ZipContents.Items[I])^;
      Z.FileName := UpperCase(Z.FileName);
      If (ExtractFileExt(Z.FileName) = '.BIN') Or
         (ExtractFileExt(Z.FileName) = '.PAL') Then
      Begin
        Item := TFileListItem.Create;
        FileList.Add(Item);
        Item.Name         := ExtractFileName(Z.FileName);
        Item.ZIPName      := Path + S.Name;
        Item.Size         := Z.UncompressedSize;
        Item.Prof         := Nil;
        Item.RNam         := '';
        Item.ScreenShot   := False;
        Item.BoxFrontScan := False;
        Item.BoxBackScan  := False;
        Item.BoxSideScan  := False;
        Item.CartScan     := False;
        Item.Manual       := False;
        Item.OverlayScan  := False;
        Item.Extras       := '';
      End;
      Inc(I);
    End; // While
  Until FindNext(S) <> 0;

  // Sort the file list in ascending alphabetical order

  For I := 0 To FileList.Count - 2 Do
  Begin
    Item := FileList[I];
    For J := I + 1 To FileList.Count - 1 Do
    Begin
      Item1 := FileList[J];
      St1 := UpperCase(Item.RNam);
      St2 := UpperCase(Item1.RNam);
      If St2 < St1 Then
      Begin
        FileList[I] := Item1;
        FileList[J] := Item;
        Item        := Item1;
      End;
    End; // For J
  End; // For I

  // Show if there were any files found

  If FileList.Count = 0 Then
  Begin
{    MenuInfo.FileName := '';}
    Close;
  End
  Else
  Begin
    LoadStringGrid;
    InterfaceHandler.ActivateInterfaces;
  End;
  Repaint;
end; // TfrmMenu.FormShow

Procedure TfrmMenu.LoadStringGrid;
Var
  I,X,Y : Integer;
  Item  : TFileListItem;
  Count : Integer;

Begin

  // Important to do this because this can be called by FormCreate, before FileList
  // has been created

  If FileList <> Nil Then Count := FileList.Count Else Count := 0;
  sgMain.DefaultColWidth  := 20 * Canvas.TextWidth('M');
  sgMain.DefaultRowHeight := Canvas.TextHeight('Mg') + 4;

  Rows := ((sgMain.Height - GetSystemMetrics(SM_CXHSCROLL) - 4) Div (sgMain.DefaultRowHeight + sgMain.GridLineWidth));
  If Rows > Count Then Rows := Count;
  If Rows > 0 Then Cols := Count Div Rows Else Cols := 0;
  If (Rows > 0) And (Count / Rows > Cols) Then Inc(Cols);

  sgMain.RowCount := Rows;
  sgMain.ColCount := Cols;
  I := 0;
  For X := 0 To Cols - 1 Do
  Begin
    For Y := 0 To Rows - 1 Do
    Begin
      If I < Count Then
      Begin
        Item := FileList[I];
        If Config.MenuDisplayScheme In [dsRealNameLeft,dsRealNameCenter]
         Then sgMain.Cells[X,Y] := Item.RNam
         Else sgMain.Cells[X,Y] := Item.Name;
        Inc(I);
      End;
    End; // For Y
  End; // For X
  sgMainClick(Self);
End; // TfrmMenu.LoadStringGrid

procedure TfrmMenu.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  If frmInfo.Visible Then frmInfo.Close;
  SaveConfiguration(Config,Version);
  InterfaceHandler.DeactivateInterfaces;
end;

Procedure TfrmMenu.ProcessChosenCart(Ch: Char; Item: TFileListItem);
Begin
  MenuInfo.FileName := Path + Item.Name;
  MenuInfo.Title    := Item.RNam;
  FindProfile(Item.Name,MenuInfo.ProfileRec);
End; // TfrmMenu.ProcessChosenCart

procedure TfrmMenu.FormKeyPress(Sender: TObject; var Key: Char);
Var
  I    : Integer;
  Item : TFileListItem;

begin
  Case UpCase(Key) Of
    #13,#27,'4','E','K':
    Begin
      If UpCase(Key) In [#13,'4','E','K'] Then
      Begin
        I := sgMain.Col * sgMain.RowCount + sgMain.Row;
        If (I >= 0) And (I < FileList.Count) Then
        Begin
          Item := FileList[I];
          ProcessChosenCart(Key,Item);
        End;
      End
      Else MenuInfo.FileName := '';
      Close;
    End;
  End; // Case
end;

procedure TfrmMenu.sgMainDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
Var
  F,B  : TColor;
  I    : Integer;
  Item : TFileListItem;
  St   : String;

  Procedure ChooseColor(X,Y: Integer);
  Begin
    If (sgMain.Col = X) And (sgMain.Row = Y) Then
    Begin
      F := clHighlightText;
      B := clHighlight;
    End
    Else
    Begin
      St := Item.RNam;
      Case Config.MenuColorScheme Of
      csGameType:
      Begin
        Case Item.Size Of
2048,4096: F := clBlack;
  8192: F := clTeal;
  8448: F := clRed;
 10495: F := clGreen;
 16384: F := clYellow;
        Else
          F := clNavy;
        End; { Case }
        If (Item.Size Mod 8448) = 0 Then F := clRed;
        B := clSilver;
      End;
      csAlphabetical:
      Begin
        If (Ord(St[1]) And 1) <> 0 Then
        Begin
          F := Config.MenuForeColor1;
          B := Config.MenuBackColor1;
        End
        Else
        Begin
          F := Config.MenuForeColor2;
          B := Config.MenuBackColor2;
        End;
      End;
      csEvery3:
      Begin
        If ((Y Div 3) And 1) <> 0 Then
        Begin
          F := Config.MenuForeColor1;
          B := Config.MenuBackColor1;
        End
        Else
        Begin
          F := Config.MenuForeColor2;
          B := Config.MenuBackColor2;
        End;
      End;
      csEvery4:
      Begin
        If ((Y Div 4) And 1) <> 0 Then
        Begin
          F := Config.MenuForeColor1;
          B := Config.MenuBackColor1;
        End
        Else
        Begin
          F := Config.MenuForeColor2;
          B := Config.MenuBackColor2;
        End;
      End;
      csEvery5:
      Begin
        If ((Y Div 5) And 1) <> 0 Then
        Begin
          F := Config.MenuForeColor1;
          B := Config.MenuBackColor1;
        End
        Else
        Begin
          F := Config.MenuForeColor2;
          B := Config.MenuBackColor2;
        End;
      End;
      csEvery6:
      Begin
        If ((Y Div 6) And 1) <> 0 Then
        Begin
          F := Config.MenuForeColor1;
          B := Config.MenuBackColor1;
        End
        Else
        Begin
          F := Config.MenuForeColor2;
          B := Config.MenuBackColor2;
        End;
      End;
      Else
        F := clBlack;
        B := clSilver;
      End; { Case }
    End;
  End; // ChooseColor

begin
  I := ACol * sgMain.RowCount + ARow;
  If (I >= 0) And (I < FileList.Count) Then
  Begin
    Item := FileList[I];
    ChooseColor(ACol,ARow);
    sgMain.Canvas.Font.Color  := F;
    sgMain.Canvas.Brush.Color := B;
    sgMain.Canvas.FillRect(Rect);
    St := Item.RNam;
    sgMain.Canvas.Font.Name  := Font.Name;
    sgMain.Canvas.Font.Size  := Font.Size;
    sgMain.Canvas.Font.Style := Font.Style;
    sgMain.Canvas.TextOut(Rect.Left + 2,Rect.Top + 2,St);
  End;
end;

procedure TfrmMenu.sgMainDblClick(Sender: TObject);
Var
  I    : Integer;
  Item : TFileListItem;

begin
  I := sgMain.Col * sgMain.RowCount + sgMain.Row;
  If (I >= 0) And (I < FileList.Count) Then
  Begin
    Item := FileList[I];
    ProcessChosenCart(#13,Item);
    Close;
  End;
end;

procedure TfrmMenu.sgMainMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var
  I    : Integer;
  Item : TFileListItem;
  St   : String;

begin
  If Button = mbRight Then
  Begin
    X := X Div (sgMain.DefaultColWidth + sgMain.GridLineWidth);
    Y := Y Div (sgMain.DefaultRowHeight + sgMain.GridLineWidth);
    I := (X + sgMain.LeftCol) * sgMain.RowCount + Y;
    If (I >= 0) And (I < FileList.Count) And (X < sgMain.ColCount) And (Y < sgMain.RowCount) Then
    Begin
      Item := FileList[I];
      St := Item.RNam;
      frmInfo.Caption  := St;
      If Not frmInfo.Visible Then frmInfo.Show;
      frmInfo.LoadImages(Item.Name);
    End;
  End;
end;

procedure TfrmMenu.sgMainClick(Sender: TObject);
Var
  I     : Integer;
  Item  : TFileListItem;
  St    : String;
  Count : Integer;

begin

  // Important to do this because this can be called by FormCreate, before FileList
  // has been created

  If FileList <> Nil Then Count := FileList.Count Else Count := 0;
  I := sgMain.Col * sgMain.RowCount + sgMain.Row;
  If (I >= 0) And (I < Count) Then
  Begin
    Item := FileList[I];
    If (Item.Prof <> Nil) And (Item.Prof.RealName <> '')
     Then St := Item.Prof.RealName + '  [' + Item.Name + ']'
     Else St := Item.Name;
    St := St + '   ' + IntToStr(Item.Size) + ' bytes';
    sbMain.Panels[0].Text := St;
  End;
end;

procedure TfrmMenu.FormDestroy(Sender: TObject);
begin
  While FileList.Count > 0 Do
  Begin
    TFileListItem(FileList[0]).Free;
    FileList.Delete(0);
  End; // While
  FileList.Free;
end;

end.

// ----------------------------------------------------------------------
// IntvWin - Mattel Intellivision Emulator
// Copyright (C) 2000 John Dullea
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------
