psx - straighten out setting of discs when loading savestates, and avoid doing likely desyncing operations in CDC module when loading savestates and setting the appropriate disc. fixes #381
This commit is contained in:
parent
62d781b960
commit
91c130a07a
|
@ -524,6 +524,20 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
||||||
return new System.Drawing.Size(VirtualWidth, VirtualHeight);
|
return new System.Drawing.Size(VirtualWidth, VirtualHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PokeDisc()
|
||||||
|
{
|
||||||
|
if (CurrentDiscIndexMounted == 0)
|
||||||
|
{
|
||||||
|
currentDiscInterface = null;
|
||||||
|
OctoshockDll.shock_PokeDisc(psx, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentDiscInterface = discInterfaces[CurrentDiscIndexMounted - 1];
|
||||||
|
OctoshockDll.shock_PokeDisc(psx, currentDiscInterface.OctoshockHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FrameAdvance_PrepDiscState()
|
void FrameAdvance_PrepDiscState()
|
||||||
{
|
{
|
||||||
//reminder: if this is the beginning of time, we can begin with the disc ejected or inserted.
|
//reminder: if this is the beginning of time, we can begin with the disc ejected or inserted.
|
||||||
|
@ -834,6 +848,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
||||||
Frame = s.ExtraData.Frame;
|
Frame = s.ExtraData.Frame;
|
||||||
CurrentTrayOpen = s.ExtraData.CurrentDiscEjected;
|
CurrentTrayOpen = s.ExtraData.CurrentDiscEjected;
|
||||||
CurrentDiscIndexMounted = s.ExtraData.CurrentDiscIndexMounted;
|
CurrentDiscIndexMounted = s.ExtraData.CurrentDiscIndexMounted;
|
||||||
|
PokeDisc();
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] savebuff;
|
byte[] savebuff;
|
||||||
|
@ -899,8 +914,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
||||||
Frame = reader.ReadInt32();
|
Frame = reader.ReadInt32();
|
||||||
CurrentTrayOpen = reader.ReadBoolean();
|
CurrentTrayOpen = reader.ReadBoolean();
|
||||||
CurrentDiscIndexMounted = reader.ReadInt32();
|
CurrentDiscIndexMounted = reader.ReadInt32();
|
||||||
|
PokeDisc();
|
||||||
//TODO - need a method to sneak the required disc, without having to do a proper eject sequence
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
||||||
[DllImport(dd, CallingConvention = cc)]
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
public static extern int shock_SetDisc(IntPtr psx, IntPtr disc);
|
public static extern int shock_SetDisc(IntPtr psx, IntPtr disc);
|
||||||
|
|
||||||
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
|
public static extern int shock_PokeDisc(IntPtr psx, IntPtr disc);
|
||||||
|
|
||||||
[DllImport(dd, CallingConvention = cc)]
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
public static extern int shock_CloseTray(IntPtr psx);
|
public static extern int shock_CloseTray(IntPtr psx);
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -62,6 +62,7 @@ PS_CDC::PS_CDC() : DMABuffer(4096)
|
||||||
{
|
{
|
||||||
IsPSXDisc = false;
|
IsPSXDisc = false;
|
||||||
Cur_disc = NULL;
|
Cur_disc = NULL;
|
||||||
|
Open_disc = NULL;
|
||||||
|
|
||||||
DriveStatus = DS_STOPPED;
|
DriveStatus = DS_STOPPED;
|
||||||
PendingCommandPhase = 0;
|
PendingCommandPhase = 0;
|
||||||
|
@ -90,33 +91,58 @@ void PS_CDC::DMForceStop(void)
|
||||||
SectorsRead = 0;
|
SectorsRead = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS_CDC::SetDisc(bool tray_open, ShockDiscRef *disc, const char *disc_id)
|
void PS_CDC::OpenTray()
|
||||||
{
|
{
|
||||||
if(tray_open)
|
//effectively a NOP at t=0
|
||||||
disc = NULL;
|
DMForceStop();
|
||||||
|
|
||||||
Cur_disc = disc;
|
//zero 31-jan-2015 - psxtech says that what this is used for is actually a 'was open' flag which gets cleared after the status gets polled.
|
||||||
|
//so lets set it here, and rename it later if we're sure.
|
||||||
|
DiscChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS_CDC::CloseTray(bool poke)
|
||||||
|
{
|
||||||
|
//switch pending (open) disc to current disc
|
||||||
|
Cur_disc = Open_disc;
|
||||||
|
Open_disc = NULL;
|
||||||
|
char disc_id[5];
|
||||||
|
strncpy(disc_id,(char*)Open_DiscID,4);
|
||||||
|
Open_DiscID[0] = 0;
|
||||||
|
|
||||||
|
//prepare analysis if disc: leave in empty state
|
||||||
IsPSXDisc = false;
|
IsPSXDisc = false;
|
||||||
memset(DiscID, 0, sizeof(DiscID));
|
memset(DiscID, 0, sizeof(DiscID));
|
||||||
|
|
||||||
if(!Cur_disc)
|
//stuff to always happen, even when poking:
|
||||||
|
if(Cur_disc)
|
||||||
{
|
{
|
||||||
DMForceStop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HeaderBufValid = false;
|
|
||||||
DiscStartupDelay = (int64)1000 * 33868800 / 1000;
|
|
||||||
DiscChanged = true;
|
|
||||||
|
|
||||||
Cur_disc->ReadTOC((ShockTOC*)&toc,(ShockTOCTrack*)toc.tracks);
|
Cur_disc->ReadTOC((ShockTOC*)&toc,(ShockTOCTrack*)toc.tracks);
|
||||||
|
|
||||||
|
//complete analysis
|
||||||
if(disc_id)
|
if(disc_id)
|
||||||
{
|
{
|
||||||
strncpy((char *)DiscID, disc_id, 4);
|
strncpy((char *)DiscID, disc_id, 4);
|
||||||
IsPSXDisc = true;
|
IsPSXDisc = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//stuff to happen when not poking (reset CDC state)
|
||||||
|
if(Cur_disc && !poke)
|
||||||
|
{
|
||||||
|
HeaderBufValid = false;
|
||||||
|
DiscStartupDelay = (int64)1000 * 33868800 / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS_CDC::SetDisc(ShockDiscRef *disc, const char *disc_id, bool poke)
|
||||||
|
{
|
||||||
|
Open_disc = disc;
|
||||||
|
strncpy((char*)Open_DiscID,disc_id,4);
|
||||||
|
|
||||||
|
if(poke)
|
||||||
|
CloseTray(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 PS_CDC::CalcNextEvent(void)
|
int32 PS_CDC::CalcNextEvent(void)
|
||||||
|
|
|
@ -26,7 +26,9 @@ class PS_CDC
|
||||||
|
|
||||||
template<bool isReader>void SyncState(EW::NewState *ns);
|
template<bool isReader>void SyncState(EW::NewState *ns);
|
||||||
|
|
||||||
void SetDisc(bool tray_open, ShockDiscRef *disc, const char disc_id[4]);
|
void OpenTray();
|
||||||
|
void SetDisc(ShockDiscRef *disc, const char disc_id[4], bool poke);
|
||||||
|
void CloseTray(bool poke);
|
||||||
|
|
||||||
void Power(void);
|
void Power(void);
|
||||||
void ResetTS(void);
|
void ResetTS(void);
|
||||||
|
@ -47,6 +49,10 @@ class PS_CDC
|
||||||
private:
|
private:
|
||||||
CDIF *Cur_CDIF;
|
CDIF *Cur_CDIF;
|
||||||
ShockDiscRef* Cur_disc;
|
ShockDiscRef* Cur_disc;
|
||||||
|
|
||||||
|
ShockDiscRef* Open_disc; //the disc that's in the tray, while the tray is open. pending, kind of. used because Cur_disc != NULL is used as a tray-closed marker in the CDC code
|
||||||
|
uint8 Open_DiscID[4]; //same thing
|
||||||
|
|
||||||
bool DiscChanged;
|
bool DiscChanged;
|
||||||
int32 DiscStartupDelay;
|
int32 DiscStartupDelay;
|
||||||
|
|
||||||
|
|
|
@ -1285,8 +1285,7 @@ EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
|
||||||
s_ShockState.power = false;
|
s_ShockState.power = false;
|
||||||
s_ShockState.eject = false;
|
s_ShockState.eject = false;
|
||||||
|
|
||||||
//set tray closed with no disc
|
//do we need to do anything particualr with the CDC disc/tray state? survey says... no.
|
||||||
CDC->SetDisc(false,NULL,"");
|
|
||||||
|
|
||||||
return SHOCK_OK;
|
return SHOCK_OK;
|
||||||
}
|
}
|
||||||
|
@ -1896,15 +1895,41 @@ EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc)
|
||||||
if(ret != SHOCK_OK) return ret;
|
if(ret != SHOCK_OK) return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_CurrDiscInfo = info;
|
||||||
|
s_CurrDisc = disc;
|
||||||
|
|
||||||
|
CDC->SetDisc(s_CurrDisc,s_CurrDiscInfo.id, false);
|
||||||
|
|
||||||
|
return SHOCK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
EW_EXPORT s32 shock_PokeDisc(void* psx, ShockDiscRef* disc)
|
||||||
|
{
|
||||||
|
//TODO HACKS! DONT COPY/PASTE SO MUCH! REFACTOR DISC ID STUFF!
|
||||||
|
|
||||||
|
//let's talk about why this function is needed. well, let's paste an old comment on the subject:
|
||||||
//heres a comment from some old savestating code. something to keep in mind (maybe or maybe not a surprise depending on your point of view)
|
//heres a comment from some old savestating code. something to keep in mind (maybe or maybe not a surprise depending on your point of view)
|
||||||
//"Call SetDisc() BEFORE we load CDC state, since SetDisc() has emulation side effects. We might want to clean this up in the future."
|
//"Call SetDisc() BEFORE we load CDC state, since SetDisc() has emulation side effects. We might want to clean this up in the future."
|
||||||
//I'm not really sure I like how SetDisc works, so I'm glad this was brought to our attention
|
//I'm not really sure I like how SetDisc works, so I'm glad this was brought to our attention
|
||||||
|
|
||||||
|
//TODO - non-psx disc is legal here. should pass null ID to CDC setdisc
|
||||||
|
|
||||||
|
//analyze disc so we dont have to annoyingly manage it from client
|
||||||
|
|
||||||
|
//TODO - so junky
|
||||||
|
ShockDiscInfo info;
|
||||||
|
strcpy(info.id,"\0\0\0\0");
|
||||||
|
info.region = REGION_NONE;
|
||||||
|
if(disc != NULL)
|
||||||
|
{
|
||||||
|
s32 ret = shock_AnalyzeDisc(disc,&info);
|
||||||
|
if(ret != SHOCK_OK) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
s_CurrDiscInfo = info;
|
s_CurrDiscInfo = info;
|
||||||
s_CurrDisc = disc;
|
s_CurrDisc = disc;
|
||||||
|
|
||||||
//set the disc to the CDC, but since its necessarily open to insert, this is false
|
CDC->SetDisc(s_CurrDisc,s_CurrDiscInfo.id,true);
|
||||||
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
|
|
||||||
|
|
||||||
return SHOCK_OK;
|
return SHOCK_OK;
|
||||||
}
|
}
|
||||||
|
@ -1913,7 +1938,7 @@ EW_EXPORT s32 shock_OpenTray(void* psx)
|
||||||
{
|
{
|
||||||
if(s_ShockState.eject) return SHOCK_NOCANDO;
|
if(s_ShockState.eject) return SHOCK_NOCANDO;
|
||||||
s_ShockState.eject = true;
|
s_ShockState.eject = true;
|
||||||
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
|
CDC->OpenTray();
|
||||||
return SHOCK_OK;
|
return SHOCK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1921,7 +1946,7 @@ EW_EXPORT s32 shock_CloseTray(void* psx)
|
||||||
{
|
{
|
||||||
if(!s_ShockState.eject) return SHOCK_NOCANDO;
|
if(!s_ShockState.eject) return SHOCK_NOCANDO;
|
||||||
s_ShockState.eject = false;
|
s_ShockState.eject = false;
|
||||||
CDC->SetDisc(false,s_CurrDisc,s_CurrDiscInfo.id);
|
CDC->CloseTray(false);
|
||||||
return SHOCK_OK;
|
return SHOCK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2106,7 +2131,6 @@ static s32 AnalyzeDiscEx(ShockDiscRef* disc, ShockDiscInfo* info)
|
||||||
uint8 buf[2048];
|
uint8 buf[2048];
|
||||||
uint8 fbuf[2048 + 1];
|
uint8 fbuf[2048 + 1];
|
||||||
unsigned ipos, opos;
|
unsigned ipos, opos;
|
||||||
int i;
|
|
||||||
|
|
||||||
//clear it out in case of error
|
//clear it out in case of error
|
||||||
info->region = REGION_NONE;
|
info->region = REGION_NONE;
|
||||||
|
|
|
@ -343,6 +343,9 @@ EW_EXPORT s32 shock_OpenTray(void* psx);
|
||||||
//Sets the disc in the tray. Returns SHOCK_NOCANDO if it's closed. You can pass NULL to remove a disc from the tray
|
//Sets the disc in the tray. Returns SHOCK_NOCANDO if it's closed. You can pass NULL to remove a disc from the tray
|
||||||
EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc);
|
EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc);
|
||||||
|
|
||||||
|
//POKES the disc in the tray, for use after loading a state. Does not affect any of the internal emulation parameters
|
||||||
|
EW_EXPORT s32 shock_PokeDisc(void* psx, ShockDiscRef* disc);
|
||||||
|
|
||||||
//Closes the disc tray. Returns SHOCK_NOCANDO if already closed.
|
//Closes the disc tray. Returns SHOCK_NOCANDO if already closed.
|
||||||
EW_EXPORT s32 shock_CloseTray(void* psx);
|
EW_EXPORT s32 shock_CloseTray(void* psx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue