This commit is contained in:
Pavel 2024-02-22 15:47:53 +03:00
parent 128a2dc369
commit 3c8b01128f
8 changed files with 318 additions and 66 deletions

View File

@ -858,6 +858,10 @@
<Filename Value="sys\md\md_game_process.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="sys\dev\display_soft.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -54,6 +54,9 @@ uses
md_game_process,
dev_dce,
display_soft,
//internal libs
ps4_libSceSystemService,
ps4_libSceUserService,
@ -66,14 +69,14 @@ uses
//
procedure TGameProcessSimple.suspend;
procedure TGameProcessSimple.suspend;
begin
thread_suspend_all(Ftd);
thread_suspend_all(nil);
end;
procedure TGameProcessSimple.resume;
procedure TGameProcessSimple.resume;
begin
thread_resume_all(Ftd);
thread_resume_all(nil);
end;
Destructor TGameProcessSimple.Destroy;
@ -122,6 +125,8 @@ begin
PROC_INIT_HOST_IPC(kern_ipc);
dev_dce.dce_interface:=display_soft.TDisplayHandleSoft;
Writeln(Item.FGameInfo.Exec);
Writeln(Item.FMountList.app0);
Writeln(Item.FMountList.system);

View File

@ -7,6 +7,10 @@ interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, Grids, Menus,
LMessages,
LCLType,
LCLIntf,
g_bufstream,
LineStream,
synlog,
@ -28,7 +32,12 @@ type
mdsRunned,
mdsSuspended);
{ TfrmMain }
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;
@ -82,6 +91,11 @@ type
FMainButtonsState:TMainButtonsState;
FGameMainForm:TGameMainForm;
function OpenMainWindows():THandle;
Procedure CloseMainWindows();
procedure ReadIniFile;
procedure LoadItemIni(Item:TGameItem);
procedure SaveItemIni(Item:TGameItem);
@ -116,7 +130,15 @@ uses
{$R *.lfm}
{ TfrmMain }
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)
@ -155,7 +177,8 @@ 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));
iKEV_EVENT :Result:=OnKevent(buf,mlen div sizeof(t_kevent));
iMAIN_WINDOWS:Result:=Form.OpenMainWindows();
else;
ShowMessage(GetEnumName(TypeInfo(mtype),ord(mtype)));
end;
@ -373,6 +396,38 @@ begin
end;
function TfrmMain.OpenMainWindows():THandle;
const
pd_Width=1280;
pd_Height=720;
begin
if (FGameMainForm<>nil) then Exit(FGameMainForm.Handle);
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.MIAddClick(Sender: TObject);
var
form:TfrmGameEditor;
@ -475,7 +530,7 @@ begin
cfg.hOutput:=FAddHandle;
cfg.hError :=FAddHandle;
cfg.fork_proc:=True;
cfg.fork_proc:=False;
FGameProcess:=run_item(cfg,Item);
@ -516,6 +571,8 @@ begin
SetButtonsState(mbsStopped);
FreeAndNil(FGameProcess);
//
CloseMainWindows;
//
Pages.ActivePage:=TabList;
end;
end;

View File

@ -18,7 +18,7 @@ uses
procedure dce_initialize();
var
dce_interface:TAbstractDisplay=TDisplayInterface;
dce_interface:TAbstractDisplay=TDisplayHandle;
dce_handle:TDisplayHandle;
@ -27,6 +27,7 @@ var
dce_page:Pointer;
knlist_lock_flip:mtx;
g_video_out_event_flip:t_knlist;
implementation
@ -58,6 +59,7 @@ begin
end;
var
callout_lock :mtx;
callout_vblank:t_callout;
callout_refs :Int64=0;
@ -65,9 +67,11 @@ procedure vblank_expire(arg:Pointer);
begin
if (callout_refs<>0) then
begin
knote_eventid(EVENTID_VBLANK, 0, 1); //SCE_VIDEO_OUT_EVENT_VBLANK
knote_eventid(EVENTID_PREVBLANK, 0, 0); //SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START
//
callout_reset(@callout_vblank, callout_vblank.c_time, @vblank_expire, nil);
//
knote_eventid(EVENTID_VBLANK, 0, 0); //SCE_VIDEO_OUT_EVENT_VBLANK
end;
end;
@ -106,10 +110,12 @@ type
paneWidth :DWORD;
paneHeight :DWORD;
refreshHz :DWORD; //Single
screenSizeInInch:DWORD;
screenSizeInInch:DWORD; //Single
padding:array[0..19] of Byte;
end;
t_scaler_info=array[0..63] of Byte;
//SCE_VIDEO_OUT_REFRESH_RATE_UNKNOWN = 0,
//SCE_VIDEO_OUT_REFRESH_RATE_23_98HZ = 1,
//SCE_VIDEO_OUT_REFRESH_RATE_50HZ = 2,
@ -157,9 +163,6 @@ type
f_0x40 :QWORD;
end;
var
flipArg:QWORD=0;
type
p_cursor_enable=^t_cursor_enable;
t_cursor_enable=packed record
@ -309,6 +312,7 @@ var
case byte of
0:(r_status:t_resolution_status);
1:(f_status:t_flip_status);
2:(i_scaler:t_scaler_info);
end;
begin
Result:=0;
@ -338,7 +342,17 @@ begin
if (dce_handle=nil) then
begin
dce_handle:=dce_interface.Open;
dce_handle:=dce_interface.Create;
if (dce_handle=nil) then
begin
Result:=EBUSY;
end else
begin
dce_handle.event_flip:=@g_video_out_event_flip;
Result:=dce_handle.Open();
end;
end else
begin
Result:=EBUSY;
@ -499,15 +513,6 @@ begin
end;
u.f_status:=Default(t_flip_status);
u.f_status.flipArg :=flipArg;
u.f_status.count :=0;
u.f_status.processTime :=0;
u.f_status.tsc :=0;
u.f_status.currentBuffer :=0;
u.f_status.flipPendingNum0:=0;
u.f_status.gcQueueNum :=0;
u.f_status.flipPendingNum1:=0;
u.f_status.submitTsc :=0;
mtx_lock(dce_mtx);
@ -544,13 +549,14 @@ begin
if (data^.arg2<>$a5a5) then Exit(EINVAL);
ptr:=Pointer(data^.arg3);
len:=QWORD (data^.arg4);
len:=0;
u.i_scaler:=Default(t_scaler_info);
Writeln('dce_flip_control(',data^.id,'):get_data?');
print_backtrace_td(stderr);
//Writeln('dce_flip_control(',data^.id,'):get_data?');
//print_backtrace_td(stderr);
Result:=copyout(@len,ptr,8);
Result:=copyout(@u.i_scaler,ptr,len);
Exit;
end;
@ -569,20 +575,9 @@ begin
if (data^.arg2<>$a5a5) then Exit(EINVAL);
ptr:=Pointer(data^.arg3);
len:=Integer(data^.arg4);
if (len>SizeOf(t_resolution_status)) then
begin
len:=SizeOf(t_resolution_status);
end;
len:=QWORD (data^.arg4);
u.r_status:=Default(t_resolution_status);
u.r_status.width :=1920;
u.r_status.heigth :=1080;
u.r_status.paneWidth :=1920;
u.r_status.paneHeight :=1080;
u.r_status.refreshHz :=$426fc28f;
u.r_status.screenSizeInInch:=32;
mtx_lock(dce_mtx);
@ -806,10 +801,6 @@ begin
'0x',HexStr(data^.flipArg,16),' ',
'0x',HexStr(data^.eop_val));
knote_eventid(EVENTID_FLIP, data^.flipArg, 0); //SCE_VIDEO_OUT_EVENT_FLIP
flipArg:=data^.flipArg;
if (data^.eop_nz=1) then
begin
Result:=copyout(@submit_eop,data^.eop_val,SizeOf(QWORD));
@ -1070,7 +1061,8 @@ begin
knlist_init_mtx(@g_video_out_event_flip,@knlist_lock_flip);
callout_init_mtx(@callout_vblank,knlist_lock_flip,0);
mtx_init(callout_lock,'vblank_lock');
callout_init_mtx(@callout_vblank,callout_lock,0);
kqueue_add_filteropts(EVFILT_DISPLAY,@filterops_display);

View File

@ -4,6 +4,17 @@ unit display_interface;
interface
uses
sys_event,
md_time;
const
EVENTID_FLIP =$0006;
EVENTID_VBLANK =$0007;
EVENTID_SETMODE =$0051;
EVENTID_POSITION =$0058;
EVENTID_PREVBLANK=$0059;
type
p_flip_status=^t_flip_status;
t_flip_status=packed record
@ -26,7 +37,7 @@ type
paneWidth :DWORD;
paneHeight :DWORD;
refreshHz :DWORD; //Single
screenSizeInInch:DWORD;
screenSizeInInch:DWORD; //Single
end;
p_register_buffer_attr=^t_register_buffer_attr;
@ -58,39 +69,56 @@ type
end;
TDisplayHandle=class
function GetFlipStatus (status:p_flip_status):Integer; virtual;
function GetResolutionStatus (status:p_resolution_status):Integer; virtual;
function SetFlipRate (rate:Integer):Integer; virtual;
function RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
function RegisterBuffer (buf:p_register_buffer):Integer; virtual;
function UnregisterBuffer (index:Integer):Integer; virtual;
function SubmitFlip (submit:p_submit_flip):Integer; virtual;
function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual;
event_flip:p_knlist;
last_status:t_flip_status;
procedure knote_eventid (event_id:WORD;flipArg:QWORD);
function Open ():Integer; virtual;
function GetFlipStatus (status:p_flip_status):Integer; virtual;
function GetResolutionStatus (status:p_resolution_status):Integer; virtual;
function SetFlipRate (rate:Integer):Integer; virtual;
function RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
function RegisterBuffer (buf:p_register_buffer):Integer; virtual;
function UnregisterBuffer (index:Integer):Integer; virtual;
function SubmitFlip (submit:p_submit_flip):Integer; virtual;
function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual;
end;
TDisplayInterface=class
class Function Open:TDisplayHandle; virtual;
end;
TAbstractDisplay=class of TDisplayInterface;
TAbstractDisplay=class of TDisplayHandle;
implementation
class Function TDisplayInterface.Open:TDisplayHandle;
//
procedure TDisplayHandle.knote_eventid(event_id:WORD;flipArg:QWORD);
begin
Result:=TDisplayHandle.Create;
knote(event_flip, event_id or (flipArg shl 16), 0);
end;
//
function TDisplayHandle.Open():Integer;
begin
last_status.currentBuffer:=DWORD(-1);
last_status.flipArg :=QWORD(-1);
Result:=0;
end;
function TDisplayHandle.GetFlipStatus(status:p_flip_status):Integer;
begin
status^:=last_status;
Result:=0;
end;
function TDisplayHandle.GetResolutionStatus(status:p_resolution_status):Integer;
begin
status^.width :=1920;
status^.heigth :=1080;
status^.paneWidth :=1920;
status^.paneHeight :=1080;
status^.refreshHz :=$426fc28f; //( 59.94)
status^.screenSizeInInch:=$42500000; //( 52.00)
//
Result:=0;
end;
@ -121,11 +149,34 @@ end;
function TDisplayHandle.SubmitFlip(submit:p_submit_flip):Integer;
begin
last_status.flipArg :=submit^.flipArg;
last_status.flipArg2 :=submit^.flipArg2;
last_status.count :=last_status.count+1;
last_status.submitTsc :=rdtsc;
last_status.currentBuffer:=submit^.bufferIndex;
knote_eventid(EVENTID_FLIP, submit^.flipArg);
last_status.tsc :=rdtsc;
last_status.processTime:=last_status.tsc;
Result:=0;
end;
function TDisplayHandle.SubmitFlipEop(submit:p_submit_flip;submit_id:QWORD):Integer;
begin
last_status.flipArg :=submit^.flipArg;
last_status.flipArg2 :=submit^.flipArg2;
last_status.count :=last_status.count+1;
last_status.submitTsc :=rdtsc;
last_status.currentBuffer:=submit^.bufferIndex;
knote_eventid(EVENTID_FLIP, submit^.flipArg);
last_status.tsc :=rdtsc;
last_status.processTime:=last_status.tsc;
Result:=0;
end;

132
sys/dev/display_soft.pas Normal file
View File

@ -0,0 +1,132 @@
unit display_soft;
{$mode ObjFPC}{$H+}
interface
uses
display_interface,
md_time;
type
p_buffer=^t_buffer;
t_buffer=packed record
attr :t_register_buffer_attr;
left :Pointer; //buffer ptr
right:Pointer; //Stereo ptr
end;
TDisplayHandleSoft=class(TDisplayHandle)
hWindow:THandle;
m_attr:array[0..3 ] of t_register_buffer_attr;
m_bufs:array[0..15] of t_buffer;
function Open ():Integer; override;
//function GetFlipStatus (status:p_flip_status):Integer; virtual;
//function GetResolutionStatus (status:p_resolution_status):Integer; virtual;
//function SetFlipRate (rate:Integer):Integer; virtual;
function RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer; override;
//function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
function RegisterBuffer (buf:p_register_buffer):Integer; override;
//function UnregisterBuffer (index:Integer):Integer; virtual;
function SubmitFlip (submit:p_submit_flip):Integer; override;
//function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual;
end;
implementation
uses
windows,
kern_proc,
kern_thr;
function TDisplayHandleSoft.Open():Integer;
begin
Result:=inherited;
Writeln('OpenMainWindows->');
hWindow:=p_proc.p_host_ipc.OpenMainWindows();
Writeln('OpenMainWindows:',hWindow);
SetWindowTextA(hWindow,'OpenMainWindows');
end;
function TDisplayHandleSoft.RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer;
begin
m_attr[attrid]:=attr^;
Result:=0;
end;
function TDisplayHandleSoft.RegisterBuffer(buf:p_register_buffer):Integer;
var
i:Integer;
begin
i:=buf^.index;
m_bufs[i].attr :=m_attr[buf^.attrid];
m_bufs[i].left :=buf^.left;
m_bufs[i].right:=buf^.right;
Result:=0;
end;
procedure SoftFlip(hWindow:THandle;buf:p_buffer);
var
hdc:THandle;
bi:BITMAPINFO;
begin
hdc:=GetDC(hWindow);
bi:=Default(BITMAPINFO);
bi.bmiHeader.biSize :=sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth :=buf^.attr.width;
bi.bmiHeader.biHeight :=buf^.attr.height;
bi.bmiHeader.biPlanes :=1;
bi.bmiHeader.biBitCount :=32;
bi.bmiHeader.biCompression:=BI_RGB;
SetDIBitsToDevice(hdc,
0, 0,
buf^.attr.width, buf^.attr.height,
0, 0,
0, buf^.attr.height,
buf^.left, bi, DIB_RGB_COLORS);
ReleaseDC(hWindow, hdc);
end;
function TDisplayHandleSoft.SubmitFlip(submit:p_submit_flip):Integer;
var
buf:p_buffer;
begin
last_status.flipArg :=submit^.flipArg;
last_status.flipArg2 :=submit^.flipArg2;
last_status.count :=last_status.count+1;
last_status.submitTsc :=rdtsc;
last_status.currentBuffer:=submit^.bufferIndex;
buf:=@m_bufs[submit^.bufferIndex];
SoftFlip(hWindow,buf);
knote_eventid(EVENTID_FLIP, submit^.flipArg);
last_status.tsc :=rdtsc;
last_status.processTime:=last_status.tsc;
Result:=0;
end;
end.

View File

@ -19,7 +19,8 @@ type
iRESULT,
iKEV_CHANGE,
iKEV_EVENT,
iMOUNT
iMOUNT,
iMAIN_WINDOWS
);
PNodeHeader=^TNodeHeader;
@ -69,6 +70,7 @@ type
public
//
procedure kevent(kev:p_kevent;count:Integer);
function OpenMainWindows():THandle;
//
function SendSync(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint;
procedure SendAsyn(mtype:t_mtype;mlen:DWORD;buf:Pointer);
@ -198,8 +200,6 @@ begin
kev :=@node^.buf;
count:=node^.header.mlen div SizeOf(t_kevent);
Writeln('RecvKevent ',kev^.ident,' ',count);
if (Fkq=nil) then
begin
Fkq:=kern_kqueue2('[ipc]',@kq_wakeup,Pointer(Self));
@ -291,6 +291,11 @@ begin
SendAsyn(iKEV_CHANGE,count*SizeOf(t_kevent),kev);
end;
function THostIpcConnect.OpenMainWindows():THandle;
begin
Result:=THandle(SendSync(iMAIN_WINDOWS,0,nil));
end;
//
function THostIpcConnect.NewNodeSync:PNodeIpcSync;

View File

@ -74,6 +74,8 @@ begin
end;
procedure t_ipc_proto.Recv;
label
_next;
var
node:PQNode;
begin
@ -87,11 +89,15 @@ begin
evbuffer_remove(Finput,@FHeader,SizeOf(TNodeHeader));
FState:=1;
if (FHeader.mlen=0) then goto _next;
end;
1:
begin
if (evbuffer_get_length(Finput)<FHeader.mlen) then Exit;
_next:
node:=AllocMem(SizeOf(TQNode)+FHeader.mlen);
node^.header:=FHeader;