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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
//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;
|
||||
CurrentTrayOpen = s.ExtraData.CurrentDiscEjected;
|
||||
CurrentDiscIndexMounted = s.ExtraData.CurrentDiscIndexMounted;
|
||||
PokeDisc();
|
||||
}
|
||||
|
||||
byte[] savebuff;
|
||||
|
@ -899,8 +914,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
Frame = reader.ReadInt32();
|
||||
CurrentTrayOpen = reader.ReadBoolean();
|
||||
CurrentDiscIndexMounted = reader.ReadInt32();
|
||||
|
||||
//TODO - need a method to sneak the required disc, without having to do a proper eject sequence
|
||||
PokeDisc();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,6 +211,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
[DllImport(dd, CallingConvention = cc)]
|
||||
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)]
|
||||
public static extern int shock_CloseTray(IntPtr psx);
|
||||
|
||||
|
|
Binary file not shown.
|
@ -62,6 +62,7 @@ PS_CDC::PS_CDC() : DMABuffer(4096)
|
|||
{
|
||||
IsPSXDisc = false;
|
||||
Cur_disc = NULL;
|
||||
Open_disc = NULL;
|
||||
|
||||
DriveStatus = DS_STOPPED;
|
||||
PendingCommandPhase = 0;
|
||||
|
@ -90,33 +91,58 @@ void PS_CDC::DMForceStop(void)
|
|||
SectorsRead = 0;
|
||||
}
|
||||
|
||||
void PS_CDC::SetDisc(bool tray_open, ShockDiscRef *disc, const char *disc_id)
|
||||
void PS_CDC::OpenTray()
|
||||
{
|
||||
if(tray_open)
|
||||
disc = NULL;
|
||||
//effectively a NOP at t=0
|
||||
DMForceStop();
|
||||
|
||||
Cur_disc = disc;
|
||||
IsPSXDisc = false;
|
||||
memset(DiscID, 0, sizeof(DiscID));
|
||||
//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;
|
||||
}
|
||||
|
||||
if(!Cur_disc)
|
||||
{
|
||||
DMForceStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
HeaderBufValid = false;
|
||||
DiscStartupDelay = (int64)1000 * 33868800 / 1000;
|
||||
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;
|
||||
|
||||
Cur_disc->ReadTOC((ShockTOC*)&toc,(ShockTOCTrack*)toc.tracks);
|
||||
//prepare analysis if disc: leave in empty state
|
||||
IsPSXDisc = false;
|
||||
memset(DiscID, 0, sizeof(DiscID));
|
||||
|
||||
if(disc_id)
|
||||
{
|
||||
strncpy((char *)DiscID, disc_id, 4);
|
||||
IsPSXDisc = true;
|
||||
}
|
||||
}
|
||||
//stuff to always happen, even when poking:
|
||||
if(Cur_disc)
|
||||
{
|
||||
Cur_disc->ReadTOC((ShockTOC*)&toc,(ShockTOCTrack*)toc.tracks);
|
||||
|
||||
//complete analysis
|
||||
if(disc_id)
|
||||
{
|
||||
strncpy((char *)DiscID, disc_id, 4);
|
||||
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)
|
||||
|
|
|
@ -26,7 +26,9 @@ class PS_CDC
|
|||
|
||||
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 ResetTS(void);
|
||||
|
@ -47,6 +49,10 @@ class PS_CDC
|
|||
private:
|
||||
CDIF *Cur_CDIF;
|
||||
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;
|
||||
int32 DiscStartupDelay;
|
||||
|
||||
|
|
|
@ -1285,8 +1285,7 @@ EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
|
|||
s_ShockState.power = false;
|
||||
s_ShockState.eject = false;
|
||||
|
||||
//set tray closed with no disc
|
||||
CDC->SetDisc(false,NULL,"");
|
||||
//do we need to do anything particualr with the CDC disc/tray state? survey says... no.
|
||||
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
@ -1896,15 +1895,41 @@ EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc)
|
|||
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)
|
||||
//"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
|
||||
|
||||
//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_CurrDisc = disc;
|
||||
|
||||
//set the disc to the CDC, but since its necessarily open to insert, this is false
|
||||
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
|
||||
CDC->SetDisc(s_CurrDisc,s_CurrDiscInfo.id,true);
|
||||
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
@ -1913,7 +1938,7 @@ EW_EXPORT s32 shock_OpenTray(void* psx)
|
|||
{
|
||||
if(s_ShockState.eject) return SHOCK_NOCANDO;
|
||||
s_ShockState.eject = true;
|
||||
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
|
||||
CDC->OpenTray();
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
||||
|
@ -1921,7 +1946,7 @@ EW_EXPORT s32 shock_CloseTray(void* psx)
|
|||
{
|
||||
if(!s_ShockState.eject) return SHOCK_NOCANDO;
|
||||
s_ShockState.eject = false;
|
||||
CDC->SetDisc(false,s_CurrDisc,s_CurrDiscInfo.id);
|
||||
CDC->CloseTray(false);
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
||||
|
@ -2106,7 +2131,6 @@ static s32 AnalyzeDiscEx(ShockDiscRef* disc, ShockDiscInfo* info)
|
|||
uint8 buf[2048];
|
||||
uint8 fbuf[2048 + 1];
|
||||
unsigned ipos, opos;
|
||||
int i;
|
||||
|
||||
//clear it out in case of error
|
||||
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
|
||||
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.
|
||||
EW_EXPORT s32 shock_CloseTray(void* psx);
|
||||
|
||||
|
|
Loading…
Reference in New Issue