mirror of https://github.com/red-prig/fpPS4.git
871 lines
16 KiB
Plaintext
871 lines
16 KiB
Plaintext
unit main;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, Grids, Menus,
|
|
|
|
LMessages,
|
|
LCLType,
|
|
LCLIntf,
|
|
|
|
g_bufstream,
|
|
LineStream,
|
|
synlog,
|
|
SynEditLineStream,
|
|
LazSynEditText,
|
|
SynEditMarkupBracket,
|
|
|
|
IniFiles,
|
|
|
|
game_info,
|
|
game_edit,
|
|
game_run,
|
|
|
|
host_ipc_interface;
|
|
|
|
type
|
|
TMainButtonsState=(mbsStopped,
|
|
mdsStarted,
|
|
mdsRunned,
|
|
mdsSuspended);
|
|
|
|
TGameMainForm=class(TForm)
|
|
public
|
|
caption_format:RawByteString;
|
|
procedure SetCaptionFPS(Ffps:QWORD);
|
|
procedure WMEraseBkgnd(var Message:TLMEraseBkgnd); message LM_ERASEBKGND;
|
|
end;
|
|
|
|
TfrmMain = class(TForm)
|
|
MainImageList: TImageList;
|
|
MIDevide3: TMenuItem;
|
|
MIRun: TMenuItem;
|
|
MIEdit: TMenuItem;
|
|
MIDevide1: TMenuItem;
|
|
MenuList: TPopupMenu;
|
|
MIAdd: TMenuItem;
|
|
MIAddFolder: TMenuItem;
|
|
MIDel: TMenuItem;
|
|
MIDevide2: TMenuItem;
|
|
Pages: TPageControl;
|
|
ListGrid: TStringGrid;
|
|
TabList: TTabSheet;
|
|
TabLog: TTabSheet;
|
|
MainToolBar: TToolBar;
|
|
TBPlay: TToolButton;
|
|
TBPause: TToolButton;
|
|
TBStop: TToolButton;
|
|
TBConfig: TToolButton;
|
|
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure OnIdleUpdate(Sender:TObject;var Done:Boolean);
|
|
procedure MIAddClick(Sender: TObject);
|
|
procedure MIAddFolderClick(Sender: TObject);
|
|
procedure MIDelClick(Sender: TObject);
|
|
procedure MIEditClick(Sender: TObject);
|
|
procedure MIRunClick(Sender: TObject);
|
|
procedure TBPauseClick(Sender: TObject);
|
|
procedure TBPlayClick(Sender: TObject);
|
|
procedure TBStopClick(Sender: TObject);
|
|
private
|
|
|
|
public
|
|
FGameProcess:TGameProcess;
|
|
FGameItem :TGameItem;
|
|
|
|
FIniFile:TIniFile;
|
|
|
|
FMainInfo:TMainInfo;
|
|
|
|
FAddHandle:THandle;
|
|
FGetHandle:THandle;
|
|
|
|
FFile:TStream;
|
|
FList:TSynEditLineStream;
|
|
|
|
Fmlog:TCustomSynLog;
|
|
|
|
FLogUpdateTime:QWORD;
|
|
|
|
FMainButtonsState:TMainButtonsState;
|
|
|
|
FGameMainForm:TGameMainForm;
|
|
|
|
function get_caption_format:RawByteString;
|
|
function OpenMainWindows():THandle;
|
|
Procedure CloseMainWindows();
|
|
Procedure ShowMainWindows();
|
|
Procedure HideMainWindows();
|
|
procedure SetCaptionFPS(Ffps:QWORD);
|
|
|
|
procedure OpenLog(Const LogFile:RawByteString);
|
|
procedure ReadIniFile;
|
|
procedure LoadItemIni(Item:TGameItem);
|
|
procedure SaveItemIni(Item:TGameItem);
|
|
function gen_section:RawByteString;
|
|
function GetItemRow(aRow:Integer):TGameItem;
|
|
procedure AddItemRow(Item:TGameItem);
|
|
procedure EditItemRow(Item:TGameItem);
|
|
procedure DelItemRow(Item:TGameItem);
|
|
procedure DoAdd(Sender: TObject);
|
|
procedure DoEdit(Sender: TObject);
|
|
procedure LogEnd;
|
|
procedure ClearLog;
|
|
function GameProcessForked:Boolean;
|
|
procedure SetButtonsState(s:TMainButtonsState);
|
|
end;
|
|
|
|
var
|
|
frmMain: TfrmMain;
|
|
|
|
implementation
|
|
|
|
uses
|
|
windows,
|
|
|
|
md_arc4random,
|
|
|
|
TypInfo,
|
|
Rtti,
|
|
|
|
sys_event;
|
|
|
|
//
|
|
|
|
{$R *.lfm}
|
|
|
|
procedure TGameMainForm.SetCaptionFPS(Ffps:QWORD);
|
|
begin
|
|
Caption:=Format(caption_format,[Ffps]);
|
|
end;
|
|
|
|
procedure TGameMainForm.WMEraseBkgnd(var Message:TLMEraseBkgnd);
|
|
begin
|
|
Message.Result:=1;
|
|
end;
|
|
|
|
type
|
|
TMySynLog=class(TCustomSynLog)
|
|
Form:TfrmMain;
|
|
constructor Create(AOwner: TComponent; AForm:TfrmMain);
|
|
function LinesCreate:TSynEditStringListBase; override;
|
|
end;
|
|
|
|
constructor TMySynLog.Create(AOwner: TComponent; AForm:TfrmMain);
|
|
begin
|
|
Form:=AForm;
|
|
inherited Create(AOwner);
|
|
end;
|
|
|
|
function TMySynLog.LinesCreate:TSynEditStringListBase;
|
|
begin
|
|
Form.FList:=TSynEditLineStream.Create;
|
|
|
|
Form.FList.FSynLog:=Self;
|
|
Form.FList.FStream:=TLineStream.Create(Form.FFile);
|
|
|
|
Result:=Form.FList;
|
|
end;
|
|
|
|
const
|
|
section_prefix='game-';
|
|
|
|
type
|
|
TGuiIpcHandler=class(THostIpcHandler)
|
|
Form:TfrmMain;
|
|
function OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; override;
|
|
function OnKevent(kev:p_kevent;count:Integer):Ptruint;
|
|
end;
|
|
|
|
function MessageDlgEx(const AMsg:RawByteString;
|
|
ADlgType:TMsgDlgType;
|
|
AButtons:TMsgDlgButtons;
|
|
AParent:TForm):TModalResult;
|
|
var
|
|
MsgFrm:TForm;
|
|
begin
|
|
MsgFrm:=CreateMessageDialog(AMsg, ADlgType, AButtons);
|
|
try
|
|
MsgFrm.Position :=poDefaultSizeOnly;
|
|
MsgFrm.FormStyle:=fsSystemStayOnTop;
|
|
MsgFrm.Left:= AParent.Left + (AParent.Width - MsgFrm.Width ) div 2;
|
|
MsgFrm.Top := AParent.Top + (AParent.Height - MsgFrm.Height) div 2;
|
|
Result:=MsgFrm.ShowModal;
|
|
finally
|
|
MsgFrm.Free
|
|
end;
|
|
end;
|
|
|
|
function TGuiIpcHandler.OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint;
|
|
begin
|
|
Result:=0;
|
|
case mtype of
|
|
iKEV_EVENT :Result:=OnKevent(buf,mlen div sizeof(t_kevent));
|
|
iMAIN_WINDOWS:Result:=Form.OpenMainWindows();
|
|
iCAPTION_FPS :Form.SetCaptionFPS(PQWORD(buf)^);
|
|
iERROR :MessageDlgEx(PChar(buf),mtError,[mbOK],Form);
|
|
else;
|
|
ShowMessage(GetEnumName(TypeInfo(mtype),ord(mtype)));
|
|
end;
|
|
end;
|
|
|
|
function TGuiIpcHandler.OnKevent(kev:p_kevent;count:Integer):Ptruint;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
Result:=0;
|
|
|
|
i:=0;
|
|
while (i<>count) do
|
|
begin
|
|
case kev[i].filter of
|
|
EVFILT_PROC:
|
|
begin
|
|
if ((kev[i].fflags and NOTE_EXIT)<>0) then
|
|
begin
|
|
//ShowMessage('NOTE_EXIT pid:'+IntToStr(kev[i].ident));
|
|
ShowMessage('The process reported exit!');
|
|
end;
|
|
if ((kev[i].fflags and NOTE_EXEC)<>0) then
|
|
begin
|
|
//ShowMessage('NOTE_EXEC pid:'+IntToStr(kev[i].ident));
|
|
Form.SetButtonsState(mdsRunned);
|
|
end;
|
|
end;
|
|
|
|
else;
|
|
end;
|
|
|
|
Inc(i);
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
var
|
|
IpcHandler:TGuiIpcHandler;
|
|
|
|
procedure TfrmMain.ReadIniFile;
|
|
var
|
|
i,c:Integer;
|
|
V:RawByteString;
|
|
//
|
|
List:TStringList;
|
|
Item:TGameItem;
|
|
begin
|
|
IpcHandler:=TGuiIpcHandler.Create;
|
|
IpcHandler.Form:=Self;
|
|
|
|
//main
|
|
FMainInfo.ReadIni(FIniFile,'main');
|
|
//main
|
|
|
|
//games
|
|
List:=TStringList.Create;
|
|
FIniFile.ReadSections(List);
|
|
|
|
c:=List.Count;
|
|
if (c<>0) then
|
|
begin
|
|
For i:=0 to c-1 do
|
|
begin
|
|
V:=Trim(List.Strings[i]);
|
|
|
|
if (lowercase(copy(v,1,Length(section_prefix)))=section_prefix) then
|
|
begin
|
|
Item:=TGameItem.Create;
|
|
Item.FSecton:=V;
|
|
|
|
LoadItemIni(Item);
|
|
//
|
|
AddItemRow(Item);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
List.Free;
|
|
//games
|
|
end;
|
|
|
|
procedure TfrmMain.LoadItemIni(Item:TGameItem);
|
|
begin
|
|
Item.FGameInfo .ReadIni(FIniFile,Item.FSecton);
|
|
Item.FMountList.ReadIni(FIniFile,Item.FSecton);
|
|
end;
|
|
|
|
procedure TfrmMain.SaveItemIni(Item:TGameItem);
|
|
begin
|
|
if (Item.FSecton='') then
|
|
begin
|
|
Item.FSecton:=gen_section;
|
|
end;
|
|
|
|
Item.FGameInfo .WriteIni(FIniFile,Item.FSecton);
|
|
Item.FMountList.WriteIni(FIniFile,Item.FSecton);
|
|
end;
|
|
|
|
function EncodeValue32(nVal:DWORD):RawByteString;
|
|
const
|
|
nEncLenMax=5;
|
|
var
|
|
i,nIdx:Integer;
|
|
begin
|
|
SetLength(Result,nEncLenMax);
|
|
For i:=nEncLenMax downto 1 do
|
|
begin
|
|
nIdx:=nVal and 63;
|
|
nVal:=nVal shr 6;
|
|
case nIdx of
|
|
0..25:Result[i]:=Char(nIdx+Byte('A')-0);
|
|
26..51:Result[i]:=Char(nIdx+Byte('a')-26);
|
|
52..61:Result[i]:=Char(nIdx+Byte('0')-52);
|
|
62:Result[i]:='+';
|
|
63:Result[i]:='-';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TfrmMain.gen_section:RawByteString;
|
|
var
|
|
nVal:DWORD;
|
|
sVal:RawByteString;
|
|
begin
|
|
nVal:=0;
|
|
arc4rand(@nVal,SizeOf(nVal),0);
|
|
|
|
sVal:=section_prefix+EncodeValue32(nVal);
|
|
|
|
while FIniFile.SectionExists(sVal) do
|
|
begin
|
|
Inc(nVal);
|
|
sVal:=section_prefix+EncodeValue32(nVal);
|
|
end;
|
|
|
|
Result:=sVal;
|
|
end;
|
|
|
|
procedure TfrmMain.OpenLog(Const LogFile:RawByteString);
|
|
var
|
|
FLogFileW:WideString;
|
|
begin
|
|
FLogFileW:=UTF8Decode(LogFile);
|
|
|
|
FAddHandle:=CreateFileW(PWideChar(FLogFileW),
|
|
GENERIC_READ or GENERIC_WRITE,
|
|
FILE_SHARE_READ,
|
|
nil,
|
|
OPEN_ALWAYS,
|
|
0,
|
|
0);
|
|
|
|
FGetHandle:=CreateFileW(PWideChar(FLogFileW),
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ or FILE_SHARE_WRITE,
|
|
nil,
|
|
OPEN_EXISTING,
|
|
0,
|
|
0);
|
|
|
|
FileSeek(FAddHandle,0,fsFromEnd);
|
|
end;
|
|
|
|
procedure TfrmMain.FormCreate(Sender: TObject);
|
|
var
|
|
r:RawByteString;
|
|
begin
|
|
FMainInfo:=TMainInfo.Create;
|
|
|
|
FIniFile:=TIniFile.Create('fpps4.ini');
|
|
|
|
ReadIniFile;
|
|
|
|
OpenLog(FMainInfo.LogFile);
|
|
|
|
if (Application.Tag<>0) then
|
|
begin
|
|
r:='Critical error, memory could not be reserved! code=0x'+HexStr(Application.Tag,8)+#13#10;
|
|
FileWrite(FAddHandle,PChar(r)^,Length(r));
|
|
ShowMessage(r);
|
|
Halt;
|
|
end;
|
|
|
|
FFile:=TBufferedFileStream.Create(FGetHandle);
|
|
|
|
Fmlog:=TMySynLog.Create(TabLog,Self);
|
|
Fmlog.Parent:=TabLog;
|
|
|
|
Fmlog.Align:=alClient;
|
|
|
|
Fmlog.BracketHighlightStyle:=sbhsBoth;
|
|
Fmlog.Font.Style:=[];
|
|
|
|
Pages.ActivePageIndex:=0;
|
|
|
|
Application.AddOnIdleHandler(@OnIdleUpdate,False);
|
|
|
|
SetButtonsState(mbsStopped);
|
|
end;
|
|
|
|
procedure TfrmMain.OnIdleUpdate(Sender:TObject;var Done:Boolean);
|
|
begin
|
|
Done:=True;
|
|
|
|
if (GetTickCount64-FLogUpdateTime)>100 then
|
|
begin
|
|
if (FList<>nil) then
|
|
begin
|
|
FList.Update;
|
|
end;
|
|
FLogUpdateTime:=GetTickCount64;
|
|
end;
|
|
|
|
if (FGameProcess<>nil) then
|
|
begin
|
|
|
|
if (FGameProcess.g_ipc<>nil) then
|
|
begin
|
|
FGameProcess.g_ipc.Update(IpcHandler);
|
|
end;
|
|
|
|
if FGameProcess.is_terminated then
|
|
begin
|
|
TBStopClick(Sender);
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
function TfrmMain.get_caption_format:RawByteString;
|
|
var
|
|
TITLE,TITLE_ID,APP_VER:RawByteString;
|
|
begin
|
|
Result:='';
|
|
|
|
if (FGameItem=nil) then Exit;
|
|
|
|
TITLE :=FGameItem.FGameInfo.Name;
|
|
TITLE_ID:=FGameItem.FGameInfo.TitleId;
|
|
APP_VER :=FGameItem.FGameInfo.Version;
|
|
|
|
if (TITLE='') then
|
|
begin
|
|
TITLE:=ExtractFileName(FGameItem.FGameInfo.Exec);
|
|
end;
|
|
|
|
if (TITLE_ID<>'') then TITLE_ID:='-' +TITLE_ID;
|
|
if (APP_VER <>'') then APP_VER :=':v'+APP_VER;
|
|
|
|
Result:=Format('fpPS4 (%s) [%s%s%s]',[{$I tag.inc},TITLE,TITLE_ID,APP_VER])+' FPS:%d';
|
|
end;
|
|
|
|
function TfrmMain.OpenMainWindows():THandle;
|
|
const
|
|
pd_Width=1280;
|
|
pd_Height=720;
|
|
begin
|
|
if (FGameMainForm<>nil) then
|
|
begin
|
|
FGameMainForm.Show;
|
|
Exit(FGameMainForm.Handle);
|
|
end;
|
|
|
|
FGameMainForm:=TGameMainForm.CreateNew(Self);
|
|
FGameMainForm.ShowInTaskBar:=stAlways;
|
|
FGameMainForm.DoubleBuffered:=False;
|
|
FGameMainForm.ParentDoubleBuffered:=False;
|
|
FGameMainForm.FormStyle:=fsNormal;
|
|
FGameMainForm.SetBounds(100, 100, pd_Width, pd_Height);
|
|
FGameMainForm.caption_format:=get_caption_format;
|
|
FGameMainForm.SetCaptionFPS(0);
|
|
//FGameMainForm.OnClose:=@FGameMainForm.CloseEvent;
|
|
//FGameMainForm.OnKeyDown:=@FGameMainForm.KeyEvent;
|
|
FGameMainForm.Position:=poScreenCenter;
|
|
|
|
///
|
|
///
|
|
|
|
FGameMainForm.Show;
|
|
|
|
Exit(FGameMainForm.Handle);
|
|
end;
|
|
|
|
Procedure TfrmMain.CloseMainWindows();
|
|
begin
|
|
FreeAndNil(FGameMainForm);
|
|
end;
|
|
|
|
Procedure TfrmMain.ShowMainWindows();
|
|
begin
|
|
if (FGameMainForm<>nil) then
|
|
begin
|
|
FGameMainForm.Show;
|
|
end;
|
|
end;
|
|
|
|
Procedure TfrmMain.HideMainWindows();
|
|
begin
|
|
if (FGameMainForm<>nil) then
|
|
begin
|
|
FGameMainForm.Hide;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMain.SetCaptionFPS(Ffps:QWORD);
|
|
begin
|
|
if (FGameMainForm=nil) then Exit;
|
|
|
|
FGameMainForm.SetCaptionFPS(Ffps);
|
|
end;
|
|
|
|
procedure TfrmMain.MIAddClick(Sender: TObject);
|
|
var
|
|
form:TfrmGameEditor;
|
|
begin
|
|
form:=TfrmGameEditor.Create(Self);
|
|
|
|
form.Item:=TGameItem.Create;
|
|
|
|
form.OnSave:=@Self.DoAdd;
|
|
|
|
form.FormInit(False);
|
|
end;
|
|
|
|
procedure TfrmMain.MIAddFolderClick(Sender: TObject);
|
|
var
|
|
d:TSelectDirectoryDialog;
|
|
form:TfrmGameEditor;
|
|
begin
|
|
d:=TSelectDirectoryDialog.Create(nil);
|
|
|
|
//d.InitialDir:=
|
|
|
|
d.Options:=[ofPathMustExist,ofEnableSizing,ofViewDetail];
|
|
|
|
if d.Execute then
|
|
begin
|
|
form:=TfrmGameEditor.Create(Self);
|
|
|
|
form.Item:=TGameItem.Create;
|
|
|
|
form.Item.FMountList.app0:=d.FileName;
|
|
|
|
form.OnSave:=@Self.DoAdd;
|
|
|
|
form.FormInit(True);
|
|
end;
|
|
|
|
d.Free;
|
|
end;
|
|
|
|
procedure TfrmMain.MIEditClick(Sender: TObject);
|
|
var
|
|
form:TfrmGameEditor;
|
|
Item:TGameItem;
|
|
aRow:Integer;
|
|
begin
|
|
aRow:=ListGrid.Row;
|
|
|
|
if (aRow=0) then Exit;
|
|
if (aRow>ListGrid.RowCount) then Exit;
|
|
|
|
Item:=GetItemRow(aRow);
|
|
|
|
if Item.FLock then Exit;
|
|
|
|
form:=TfrmGameEditor.Create(Self);
|
|
|
|
form.Item:=Item;
|
|
|
|
Item.FLock:=True;
|
|
|
|
form.OnSave:=@Self.DoEdit;
|
|
|
|
form.FormInit(False);
|
|
end;
|
|
|
|
procedure TfrmMain.LogEnd;
|
|
begin
|
|
Fmlog.TopLine:=Fmlog.Lines.Count;
|
|
end;
|
|
|
|
procedure TfrmMain.ClearLog;
|
|
begin
|
|
//reset file
|
|
FileTruncate(FAddHandle,0);
|
|
FList.Reset;
|
|
//
|
|
end;
|
|
|
|
procedure TfrmMain.MIRunClick(Sender: TObject);
|
|
var
|
|
Item:TGameItem;
|
|
aRow:Integer;
|
|
cfg:TGameRunConfig;
|
|
begin
|
|
if (FGameProcess<>nil) then Exit;
|
|
|
|
aRow:=ListGrid.Row;
|
|
|
|
if (aRow=0) then Exit;
|
|
if (aRow>ListGrid.RowCount) then Exit;
|
|
|
|
Item:=GetItemRow(aRow);
|
|
|
|
LogEnd;
|
|
ClearLog;
|
|
|
|
Pages.ActivePage:=TabLog;
|
|
|
|
cfg.hOutput:=FAddHandle;
|
|
cfg.hError :=FAddHandle;
|
|
|
|
cfg.fork_proc:=True;
|
|
|
|
if Item.FLock then Exit;
|
|
|
|
FGameProcess:=run_item(cfg,Item);
|
|
|
|
if (FGameProcess<>nil) then
|
|
begin
|
|
Item.FLock:=True;
|
|
FGameItem:=Item;
|
|
|
|
SetButtonsState(mdsStarted);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMain.TBPlayClick(Sender: TObject);
|
|
begin
|
|
if (FGameProcess<>nil) then
|
|
begin
|
|
//resume
|
|
ShowMainWindows();
|
|
FGameProcess.resume;
|
|
SetButtonsState(mdsRunned);
|
|
end else
|
|
begin
|
|
//run
|
|
MIRunClick(Sender);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMain.TBPauseClick(Sender: TObject);
|
|
begin
|
|
if (FGameProcess<>nil) then
|
|
begin
|
|
//suspend
|
|
FGameProcess.suspend;
|
|
SetButtonsState(mdsSuspended);
|
|
end;
|
|
end;
|
|
|
|
function TfrmMain.GameProcessForked:Boolean;
|
|
begin
|
|
Result:=False;
|
|
if (FGameProcess<>nil) then
|
|
begin
|
|
Result:=FGameProcess.g_fork;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMain.TBStopClick(Sender: TObject);
|
|
begin
|
|
if GameProcessForked then //only forked
|
|
begin
|
|
//terminate
|
|
FGameProcess.stop;
|
|
SetButtonsState(mbsStopped);
|
|
FreeAndNil(FGameProcess);
|
|
//
|
|
if (FGameItem<>nil) then
|
|
begin
|
|
FGameItem.FLock:=False;
|
|
FGameItem:=nil;
|
|
end;
|
|
//
|
|
CloseMainWindows;
|
|
//
|
|
Pages.ActivePage:=TabList;
|
|
end else
|
|
begin
|
|
TBPauseClick(Sender);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMain.MIDelClick(Sender: TObject);
|
|
var
|
|
Item:TGameItem;
|
|
aRow:Integer;
|
|
begin
|
|
aRow:=ListGrid.Row;
|
|
|
|
if (aRow=0) then Exit;
|
|
if (aRow>ListGrid.RowCount) then Exit;
|
|
|
|
Item:=GetItemRow(aRow);
|
|
|
|
if (Item.FLock) then Exit;
|
|
|
|
if (MessageDlg('Question',
|
|
'Remove item "'+Item.FGameInfo.Name+'" from list?',
|
|
mtConfirmation,
|
|
[mbYes, mbNo],
|
|
0)=mrYes) then
|
|
begin
|
|
FIniFile.EraseSection(Item.FSecton);
|
|
//
|
|
DelItemRow(Item);
|
|
end;
|
|
end;
|
|
|
|
function TfrmMain.GetItemRow(aRow:Integer):TGameItem;
|
|
begin
|
|
Result:=nil;
|
|
//
|
|
if (aRow=0) then Exit;
|
|
if (aRow>ListGrid.RowCount) then Exit;
|
|
//
|
|
Result:=TGameItem(ListGrid.Objects[0,aRow]);
|
|
end;
|
|
|
|
procedure TfrmMain.AddItemRow(Item:TGameItem);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
i:=ListGrid.RowCount;
|
|
ListGrid.RowCount:=i+1;
|
|
ListGrid.Cells[0,i]:=Item.FGameInfo.Name;
|
|
ListGrid.Cells[1,i]:=Item.FGameInfo.TitleId;
|
|
ListGrid.Cells[2,i]:=Item.FGameInfo.Version;
|
|
//
|
|
ListGrid.Objects[0,i]:=Item;
|
|
end;
|
|
|
|
procedure TfrmMain.EditItemRow(Item:TGameItem);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
i:=ListGrid.Cols[0].IndexOfObject(Item);
|
|
if (i=-1) then Exit;
|
|
//
|
|
ListGrid.Cells[0,i]:=Item.FGameInfo.Name;
|
|
ListGrid.Cells[1,i]:=Item.FGameInfo.TitleId;
|
|
ListGrid.Cells[2,i]:=Item.FGameInfo.Version;
|
|
end;
|
|
|
|
procedure TfrmMain.DelItemRow(Item:TGameItem);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
i:=ListGrid.Cols[0].IndexOfObject(Item);
|
|
if (i=-1) then Exit;
|
|
//
|
|
ListGrid.DeleteRow(i);
|
|
//
|
|
Item.Free;
|
|
end;
|
|
|
|
procedure TfrmMain.DoAdd(Sender: TObject);
|
|
var
|
|
form:TfrmGameEditor;
|
|
Item:TGameItem;
|
|
begin
|
|
form:=TfrmGameEditor(Sender);
|
|
|
|
Item:=form.Item;
|
|
|
|
form.Item:=nil;
|
|
|
|
AddItemRow(Item);
|
|
SaveItemIni(Item);
|
|
end;
|
|
|
|
procedure TfrmMain.DoEdit(Sender: TObject);
|
|
var
|
|
form:TfrmGameEditor;
|
|
Item:TGameItem;
|
|
begin
|
|
form:=TfrmGameEditor(Sender);
|
|
|
|
Item:=form.Item;
|
|
|
|
Item.FLock:=False;
|
|
|
|
form.Item:=nil;
|
|
|
|
EditItemRow(Item);
|
|
SaveItemIni(Item);
|
|
end;
|
|
|
|
procedure TfrmMain.SetButtonsState(s:TMainButtonsState);
|
|
begin
|
|
FMainButtonsState:=s;
|
|
|
|
case s of
|
|
mbsStopped:
|
|
begin
|
|
TBPlay .Enabled:=True;
|
|
TBPause.Enabled:=False;
|
|
TBStop .Enabled:=False;
|
|
//
|
|
TBPlay .ImageIndex:=0;
|
|
TBPause.ImageIndex:=1+3;
|
|
TBStop .ImageIndex:=2+3;
|
|
end;
|
|
mdsStarted:
|
|
begin
|
|
TBPlay .Enabled:=False;
|
|
TBPause.Enabled:=False;
|
|
TBStop .Enabled:=False;
|
|
//
|
|
TBPlay .ImageIndex:=0+3;
|
|
TBPause.ImageIndex:=1+3;
|
|
TBStop .ImageIndex:=2+3;
|
|
end;
|
|
mdsRunned:
|
|
begin
|
|
TBPlay .Enabled:=False;
|
|
TBPause.Enabled:=True;
|
|
TBStop .Enabled:=False;
|
|
//
|
|
TBPlay .ImageIndex:=0+3;
|
|
TBPause.ImageIndex:=1;
|
|
TBStop .ImageIndex:=2+3;
|
|
|
|
if GameProcessForked then //only forked
|
|
begin
|
|
TBStop .Enabled:=True;
|
|
|
|
TBStop .ImageIndex:=2;
|
|
end;
|
|
end;
|
|
mdsSuspended:
|
|
begin
|
|
TBPlay .Enabled:=True;
|
|
TBPause.Enabled:=False;
|
|
TBStop .Enabled:=False;
|
|
//
|
|
TBPlay .ImageIndex:=0;
|
|
TBPause.ImageIndex:=1+3;
|
|
TBStop .ImageIndex:=2+3;
|
|
|
|
if GameProcessForked then //only forked
|
|
begin
|
|
TBStop .Enabled:=True;
|
|
|
|
TBStop .ImageIndex:=2;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
end.
|
|
|
|
|