Compare commits

...

5 Commits

Author SHA1 Message Date
Timothy O'Barr 9895047206
Merge 759ffa6d6c into 5486eed151 2024-09-18 15:27:47 -07:00
lightningterror 5486eed151 GS/HW: Merge blend ad a mask separate conditions in to one.
Duplicate code.
2024-09-19 00:19:05 +02:00
Ty Lamontagne d1721360ff
DebugInterface: Fix formatting 2024-09-18 16:57:20 -04:00
weirdbeardgame 759ffa6d6c CDVD: 0 index into tracks array 2024-09-16 13:58:01 -07:00
weirdbeardgame fae15404d9 CDVD: Added cdvdTrack, cdvdTrackIndex
used IOCtl SubQ reads to get proper control register
Added Checks for Control fields.
2024-09-16 13:32:23 -07:00
10 changed files with 149 additions and 47 deletions

View File

@ -52,6 +52,11 @@ u32 lastLSN; // needed for block dumping
static OutputIsoFile blockDumpFile; static OutputIsoFile blockDumpFile;
// Information about tracks on disc
u8 strack;
u8 etrack;
cdvdTrack tracks[100];
// Assertion check for CDVD != NULL (in devel and debug builds), because its handier than // Assertion check for CDVD != NULL (in devel and debug builds), because its handier than
// relying on DEP exceptions -- and a little more reliable too. // relying on DEP exceptions -- and a little more reliable too.
static void CheckNullCDVD() static void CheckNullCDVD()

View File

@ -10,19 +10,48 @@
class Error; class Error;
class ProgressCallback; class ProgressCallback;
typedef struct _cdvdSubQ typedef struct _cdvdTrackIndex
{ {
u8 ctrl : 4; // control and mode bits bool isPregap;
u8 mode : 4; // control and mode bits u8 trackM; // current minute offset from first track (BCD encoded)
u8 trackS; // current sector offset from first track (BCD encoded)
u8 trackF; // current frame offset from first track (BCD encoded)
u8 discM; // current minute location on the disc (BCD encoded)
u8 discS; // current sector location on the disc (BCD encoded)
u8 discF; // current frame location on the disc (BCD encoded)
} cdvdTrackIndex;
typedef struct _cdvdTrack
{
u32 start_lba; // Starting lba of track, note that some formats will be missing 2 seconds, cue, bin
u8 type; // Track Type
u8 trackNum; // current track number (1 to 99) u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99) u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute location on the disc (BCD encoded) u8 trackM; // current minute offset from first track (BCD encoded)
u8 trackS; // current sector location on the disc (BCD encoded) u8 trackS; // current sector offset from first track (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded) u8 trackF; // current frame offset from first track (BCD encoded)
u8 discM; // current minute location on the disc (BCD encoded)
u8 discS; // current sector location on the disc (BCD encoded)
u8 discF; // current frame location on the disc (BCD encoded)
// 0 is pregap, 1 is data
_cdvdTrackIndex index[2];
} cdvdTrack;
typedef struct _cdvdSubQ
{
u8 ctrl : 4; // control and adr bits
u8 adr : 4; // control and adr bits, note that adr determines what SubQ info we're recieving.
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute offset from first track (BCD encoded)
u8 trackS; // current sector offset from first track (BCD encoded)
u8 trackF; // current frame offset from first track (BCD encoded)
u8 pad; // unused u8 pad; // unused
u8 discM; // current minute offset from first track (BCD encoded) u8 discM; // current minute location on the disc (BCD encoded)
u8 discS; // current sector offset from first track (BCD encoded) u8 discS; // current sector location on the disc (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded) u8 discF; // current frame location on the disc (BCD encoded)
} cdvdSubQ; } cdvdSubQ;
typedef struct _cdvdTD typedef struct _cdvdTD
@ -65,6 +94,12 @@ typedef struct _cdvdTN
#define CDVD_TYPE_DETCT 0x01 // Detecting #define CDVD_TYPE_DETCT 0x01 // Detecting
#define CDVD_TYPE_NODISC 0x00 // No Disc #define CDVD_TYPE_NODISC 0x00 // No Disc
// SUBQ CONTROL:
#define CDVD_CONTROL_AUDIO_PREEMPHASIS(control) ((control & (4 << 1)))
#define CDVD_CONTROL_DIGITAL_COPY_ALLOWED(control) ((control & (5 << 1)))
#define CDVD_CONTROL_IS_DATA(control) ((control & (6 << 1))) // Detects if track is Data or Audio
#define CDVD_CONTROL_IS_QUADRAPHONIC_AUDIO(control) ((control & (7 << 1)))
// CDVDgetTrayStatus returns: // CDVDgetTrayStatus returns:
#define CDVD_TRAY_CLOSE 0x00 #define CDVD_TRAY_CLOSE 0x00
#define CDVD_TRAY_OPEN 0x01 #define CDVD_TRAY_OPEN 0x01
@ -148,6 +183,10 @@ extern const CDVD_API CDVDapi_Iso;
extern const CDVD_API CDVDapi_Disc; extern const CDVD_API CDVDapi_Disc;
extern const CDVD_API CDVDapi_NoDisc; extern const CDVD_API CDVDapi_NoDisc;
extern u8 strack;
extern u8 etrack;
extern cdvdTrack tracks[100];
extern void CDVDsys_ChangeSource(CDVD_SourceType type); extern void CDVDsys_ChangeSource(CDVD_SourceType type);
extern void CDVDsys_SetFile(CDVD_SourceType srctype, std::string newfile); extern void CDVDsys_SetFile(CDVD_SourceType srctype, std::string newfile);
extern const std::string& CDVDsys_GetFile(CDVD_SourceType srctype); extern const std::string& CDVDsys_GetFile(CDVD_SourceType srctype);

View File

@ -4,6 +4,7 @@
#include "CDVDdiscReader.h" #include "CDVDdiscReader.h"
#include "CDVD/CDVD.h" #include "CDVD/CDVD.h"
#include "Host.h" #include "Host.h"
#include "common/Console.h"
#include "common/Error.h" #include "common/Error.h"
@ -23,10 +24,6 @@ static std::thread s_keepalive_thread;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// State Information // // State Information //
u8 strack;
u8 etrack;
track tracks[100];
int curDiskType; int curDiskType;
int curTrayStatus; int curTrayStatus;
@ -79,31 +76,35 @@ void cdvdParseTOC()
strack = 0xFF; strack = 0xFF;
etrack = 0; etrack = 0;
int i = 0;
for (auto& entry : src->ReadTOC()) for (auto& entry : src->ReadTOC())
{ {
if (entry.track < 1 || entry.track > 99) if (entry.track < 1 || entry.track > 99)
continue; continue;
strack = std::min(strack, entry.track); strack = std::min(strack, entry.track);
etrack = std::max(etrack, entry.track); etrack = std::max(etrack, entry.track);
tracks[entry.track].start_lba = entry.lba; tracks[i].start_lba = entry.lba;
if ((entry.control & 0x0C) == 0x04) if ((entry.control & 0x0C) == 0x04)
{ {
std::array<u8, 2352> buffer; std::array<u8, 2352> buffer;
// Byte 15 of a raw CD data sector determines the track mode // Byte 15 of a raw CD data sector determines the track mode
if (src->ReadSectors2352(entry.lba, 1, buffer.data()) && (buffer[15] & 3) == 2) if (src->ReadSectors2352(entry.lba, 1, buffer.data()) && (buffer[15] & 3) == 2)
{ {
tracks[entry.track].type = CDVD_MODE2_TRACK; tracks[i].type = CDVD_MODE2_TRACK;
} }
else else
{ {
tracks[entry.track].type = CDVD_MODE1_TRACK; tracks[i].type = CDVD_MODE1_TRACK;
} }
} }
else else
{ {
tracks[entry.track].type = CDVD_AUDIO_TRACK; tracks[i].type = CDVD_AUDIO_TRACK;
} }
fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba); fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba);
i += 1;
} }
} }
@ -270,20 +271,23 @@ static s32 DISCreadSubQ(u32 lsn, cdvdSubQ* subq)
memset(subq, 0, sizeof(cdvdSubQ)); memset(subq, 0, sizeof(cdvdSubQ));
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150); if (!src->ReadTrackSubQ(subq))
{
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);
u8 i = strack; u8 i = strack;
while (i < etrack && lsn >= tracks[i + 1].start_lba) while (i < etrack && lsn >= tracks[i + 1].start_lba)
++i; ++i;
lsn -= tracks[i].start_lba; lsn -= tracks[i].start_lba;
lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn); lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn);
subq->mode = 1; subq->adr = 1;
subq->ctrl = tracks[i].type; subq->ctrl = tracks[i].type;
subq->trackNum = i; subq->trackNum = i;
subq->trackIndex = 1; subq->trackIndex = 1;
}
return 0; return 0;
} }

View File

@ -7,6 +7,7 @@
#include "common/RedtapeWindows.h" #include "common/RedtapeWindows.h"
#endif #endif
#include "CDVDcommon.h"
#include "common/Pcsx2Defs.h" #include "common/Pcsx2Defs.h"
#include <array> #include <array>
@ -17,16 +18,6 @@
class Error; class Error;
struct track
{
u32 start_lba;
u8 type;
};
extern u8 strack;
extern u8 etrack;
extern track tracks[100];
extern int curDiskType; extern int curDiskType;
extern int curTrayStatus; extern int curTrayStatus;
@ -70,6 +61,7 @@ public:
const std::vector<toc_entry>& ReadTOC() const; const std::vector<toc_entry>& ReadTOC() const;
bool ReadSectors2048(u32 sector, u32 count, u8* buffer) const; bool ReadSectors2048(u32 sector, u32 count, u8* buffer) const;
bool ReadSectors2352(u32 sector, u32 count, u8* buffer) const; bool ReadSectors2352(u32 sector, u32 count, u8* buffer) const;
bool ReadTrackSubQ(cdvdSubQ* subq) const;
u32 GetLayerBreakAddress() const; u32 GetLayerBreakAddress() const;
s32 GetMediaType() const; s32 GetMediaType() const;
void SetSpindleSpeed(bool restore_defaults) const; void SetSpindleSpeed(bool restore_defaults) const;

View File

@ -65,7 +65,7 @@ static s32 ISOreadSubQ(u32 lsn, cdvdSubQ* subq)
// fake it // fake it
u8 min, sec, frm; u8 min, sec, frm;
subq->ctrl = 4; subq->ctrl = 4;
subq->mode = 1; subq->adr = 1;
subq->trackNum = itob(1); subq->trackNum = itob(1);
subq->trackIndex = itob(1); subq->trackIndex = itob(1);

View File

@ -241,6 +241,11 @@ bool IOCtlSrc::ReadCDInfo()
#endif #endif
} }
bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
{
return false;
}
bool IOCtlSrc::DiscReady() bool IOCtlSrc::DiscReady()
{ {
#ifdef __APPLE__ #ifdef __APPLE__

View File

@ -5,6 +5,7 @@
#include "CDVD/CDVD.h" #include "CDVD/CDVD.h"
#include "common/Error.h" #include "common/Error.h"
#include "common/Console.h"
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <fcntl.h> #include <fcntl.h>
@ -194,6 +195,35 @@ bool IOCtlSrc::ReadCDInfo()
return true; return true;
} }
bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
{
cdrom_subchnl osSubQ;
osSubQ.cdsc_format = CDROM_MSF;
if (ioctl(m_device, CDROMSUBCHNL, &osSubQ) == -1)
{
Console.Error("SUB CHANNEL READ ERROR: %s\n", strerror(errno));
return false;
}
subQ->adr = osSubQ.cdsc_adr;
subQ->ctrl = osSubQ.cdsc_ctrl;
subQ->trackNum = osSubQ.cdsc_trk;
subQ->trackIndex = osSubQ.cdsc_ind;
subQ->discM = osSubQ.cdsc_absaddr.msf.minute;
subQ->discS = osSubQ.cdsc_absaddr.msf.second;
subQ->discF = osSubQ.cdsc_absaddr.msf.frame;
subQ->trackM = osSubQ.cdsc_reladdr.msf.minute;
subQ->trackS = osSubQ.cdsc_reladdr.msf.second;
subQ->trackF = osSubQ.cdsc_reladdr.msf.frame;
return true;
}
bool IOCtlSrc::DiscReady() bool IOCtlSrc::DiscReady()
{ {
if (m_device == -1) if (m_device == -1)

View File

@ -10,6 +10,7 @@
#include <winioctl.h> #include <winioctl.h>
#include <ntddcdvd.h> #include <ntddcdvd.h>
#include <ntddcdrm.h> #include <ntddcdrm.h>
#include <errno.h>
// "typedef ignored" warning will disappear once we move to the Windows 10 SDK. // "typedef ignored" warning will disappear once we move to the Windows 10 SDK.
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4091) #pragma warning(disable : 4091)
@ -303,6 +304,38 @@ bool IOCtlSrc::ReadCDInfo()
return true; return true;
} }
bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
{
CDROM_SUB_Q_DATA_FORMAT format;
SUB_Q_CHANNEL_DATA osSubQ{};
DWORD unused;
format.Format = IOCTL_CDROM_CURRENT_POSITION;
if (!DeviceIoControl(m_device, IOCTL_CDROM_READ_Q_CHANNEL, &format, sizeof(format), &osSubQ, sizeof(osSubQ), &unused, nullptr))
{
Console.Error("SUB CHANNEL READ ERROR: %d\n", errno);
return false;
}
else
{
subQ->adr = osSubQ.CurrentPosition.ADR;
subQ->ctrl = osSubQ.CurrentPosition.Control;
subQ->trackNum = osSubQ.CurrentPosition.TrackNumber;
subQ->trackIndex = osSubQ.CurrentPosition.IndexNumber;
subQ->trackM = osSubQ.CurrentPosition.TrackRelativeAddress[0];
subQ->trackS = osSubQ.CurrentPosition.TrackRelativeAddress[1];
subQ->trackF = osSubQ.CurrentPosition.TrackRelativeAddress[2];
subQ->discM = osSubQ.CurrentPosition.AbsoluteAddress[0];
subQ->discS = osSubQ.CurrentPosition.AbsoluteAddress[1];
subQ->discF = osSubQ.CurrentPosition.AbsoluteAddress[2];
}
return true;
}
bool IOCtlSrc::DiscReady() bool IOCtlSrc::DiscReady()
{ {
if (m_device == INVALID_HANDLE_VALUE) if (m_device == INVALID_HANDLE_VALUE)

View File

@ -829,7 +829,7 @@ bool R5900DebugInterface::isValidAddress(u32 addr)
break; break;
case 8: case 8:
case 0xA: case 0xA:
if(lopart <= 0xFFFFF) if (lopart <= 0xFFFFF)
return true; return true;
break; break;
case 9: case 9:

View File

@ -4208,14 +4208,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
const bool alpha_mask = (m_cached_ctx.FRAME.FBMSK & 0xFF000000) == 0xFF000000; const bool alpha_mask = (m_cached_ctx.FRAME.FBMSK & 0xFF000000) == 0xFF000000;
bool blend_ad_alpha_masked = blend_ad && alpha_mask; bool blend_ad_alpha_masked = blend_ad && alpha_mask;
const bool is_basic_blend = GSConfig.AccurateBlendingUnit >= AccBlendLevel::Basic; const bool is_basic_blend = GSConfig.AccurateBlendingUnit >= AccBlendLevel::Basic;
if ((is_basic_blend || (COLCLAMP.CLAMP == 0)) && features.texture_barrier && blend_ad_alpha_masked) if (blend_ad_alpha_masked && (((is_basic_blend || (COLCLAMP.CLAMP == 0)) && features.texture_barrier)
{ || ((GSConfig.AccurateBlendingUnit >= AccBlendLevel::Medium) || m_conf.require_one_barrier)))
// Swap Ad with As for hw blend.
m_conf.ps.a_masked = 1;
m_conf.ps.blend_c = 0;
m_conf.require_one_barrier |= true;
}
else if (((GSConfig.AccurateBlendingUnit >= AccBlendLevel::Medium) || m_conf.require_one_barrier) && blend_ad_alpha_masked)
{ {
// Swap Ad with As for hw blend. // Swap Ad with As for hw blend.
m_conf.ps.a_masked = 1; m_conf.ps.a_masked = 1;