mirror of https://github.com/PCSX2/pcsx2.git
Remove CDVDPeops and PeopsSPU2. (#2792)
This commit is contained in:
parent
54f8aca7d5
commit
c58acd1105
|
@ -19,7 +19,6 @@
|
||||||
*.dump
|
*.dump
|
||||||
|
|
||||||
*.asm
|
*.asm
|
||||||
!/plugins/CDVDpeops/i386.asm
|
|
||||||
!/plugins/zerogs/dx/x86-32.asm
|
!/plugins/zerogs/dx/x86-32.asm
|
||||||
!/plugins/zerogs/dx/x86-64.asm
|
!/plugins/zerogs/dx/x86-64.asm
|
||||||
!/plugins/zerogs/opengl/x86-32.asm
|
!/plugins/zerogs/opengl/x86-32.asm
|
||||||
|
@ -96,7 +95,6 @@ oprofile_data/
|
||||||
/3rdparty/**/wx/msw/rcdefs.h
|
/3rdparty/**/wx/msw/rcdefs.h
|
||||||
/pcsx2/gui/Resources/*.h
|
/pcsx2/gui/Resources/*.h
|
||||||
!/pcsx2/gui/Resources/EmbeddedImage.h
|
!/pcsx2/gui/Resources/EmbeddedImage.h
|
||||||
/plugins/CDVDolio/Template
|
|
||||||
/plugins/GSdx/Template
|
/plugins/GSdx/Template
|
||||||
/plugins/USBqemu/Win32/bin
|
/plugins/USBqemu/Win32/bin
|
||||||
/plugins/xpad/Template
|
/plugins/xpad/Template
|
||||||
|
|
|
@ -306,12 +306,7 @@ if(GTKn_FOUND)
|
||||||
endif()
|
endif()
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Super-seeded by cdvdGigaherz
|
|
||||||
set(CDVDpeops FALSE)
|
|
||||||
|
|
||||||
# [TODO] Write CMakeLists.txt for these plugins. (or not ;) )
|
# [TODO] Write CMakeLists.txt for these plugins. (or not ;) )
|
||||||
set(PeopsSPU2 FALSE)
|
|
||||||
set(SSSPSXPAD FALSE)
|
set(SSSPSXPAD FALSE)
|
||||||
set(xpad FALSE)
|
set(xpad FALSE)
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
|
@ -91,7 +91,7 @@ remove_not_yet_free_plugin()
|
||||||
{
|
{
|
||||||
echo "Remove non free plugins"
|
echo "Remove non free plugins"
|
||||||
# remove also deprecated plugins
|
# remove also deprecated plugins
|
||||||
for plugin in CDVDiso CDVDisoEFP CDVDlinuz CDVDolio CDVDpeops PeopsSPU2 SSSPSXPAD USBqemu xpad zerogs zerospu2
|
for plugin in CDVDiso SSSPSXPAD USBqemu xpad zerogs zerospu2
|
||||||
do
|
do
|
||||||
rm -fr $LOCAL_REPO/plugins/$plugin
|
rm -fr $LOCAL_REPO/plugins/$plugin
|
||||||
done
|
done
|
||||||
|
|
|
@ -46,14 +46,9 @@ fi
|
||||||
files=`git diff --name-only --diff-filter=ACMRT $diff_range -- $PWD | \
|
files=`git diff --name-only --diff-filter=ACMRT $diff_range -- $PWD | \
|
||||||
grep "\.\(c\|h\|inl\|cpp\|hpp\)$" | \
|
grep "\.\(c\|h\|inl\|cpp\|hpp\)$" | \
|
||||||
grep -v "${1}pcsx2/" | \
|
grep -v "${1}pcsx2/" | \
|
||||||
grep -v "${1}plugins/CDVDisoEFP/" | \
|
|
||||||
grep -v "${1}plugins/CDVDlinuz/" | \
|
|
||||||
grep -v "${1}plugins/CDVDolio/" | \
|
|
||||||
grep -v "${1}plugins/CDVDpeops/" | \
|
|
||||||
grep -v "${1}plugins/dev9ghzdrk/" | \
|
grep -v "${1}plugins/dev9ghzdrk/" | \
|
||||||
grep -v "${1}plugins/GSdx/" | \
|
grep -v "${1}plugins/GSdx/" | \
|
||||||
grep -v "${1}plugins/GSdx_legacy/" | \
|
grep -v "${1}plugins/GSdx_legacy/" | \
|
||||||
grep -v "${1}plugins/PeopsSPU2/" | \
|
|
||||||
grep -v "${1}plugins/SSSPSXPAD/" | \
|
grep -v "${1}plugins/SSSPSXPAD/" | \
|
||||||
grep -v "${1}plugins/USBqemu/" | \
|
grep -v "${1}plugins/USBqemu/" | \
|
||||||
grep -v "${1}plugins/xpad/" | \
|
grep -v "${1}plugins/xpad/" | \
|
||||||
|
|
|
@ -1,822 +0,0 @@
|
||||||
/*
|
|
||||||
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
|
|
||||||
* Modified by Florin for PCSX2 emu
|
|
||||||
* Fixed CdRead by linuzappz
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef __linux__
|
|
||||||
#define strnicmp strncasecmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "CDVDiso.h"
|
|
||||||
#include "CDVDisodrv.h"
|
|
||||||
|
|
||||||
struct dir_toc_data{
|
|
||||||
unsigned int start_LBA;
|
|
||||||
unsigned int num_sectors;
|
|
||||||
unsigned int num_entries;
|
|
||||||
unsigned int current_entry;
|
|
||||||
unsigned int current_sector;
|
|
||||||
unsigned int current_sector_offset;
|
|
||||||
unsigned int inc_dirs;
|
|
||||||
unsigned char extension_list[128+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
//static u8 cdVolDescriptor[2048];
|
|
||||||
static struct dir_toc_data getDirTocData;
|
|
||||||
static struct cdVolDesc CDVolDesc;
|
|
||||||
|
|
||||||
void _splitpath2(const char *constpath, char *dir, char *fname){
|
|
||||||
// 255 char max path-length is an ISO9660 restriction
|
|
||||||
// we must change this for Joliet or relaxed iso restriction support
|
|
||||||
static char pathcopy[1024+1];
|
|
||||||
|
|
||||||
char* slash;
|
|
||||||
|
|
||||||
strncpy(pathcopy, constpath, 1024);
|
|
||||||
|
|
||||||
slash = strrchr (pathcopy, '/');
|
|
||||||
|
|
||||||
// if the path doesn't contain a '/' then look for a '\'
|
|
||||||
if (!slash)
|
|
||||||
slash = strrchr (pathcopy, (int)'\\');
|
|
||||||
|
|
||||||
// if a slash was found
|
|
||||||
if (slash != NULL)
|
|
||||||
{
|
|
||||||
// null terminate the path
|
|
||||||
slash[0] = 0;
|
|
||||||
// and copy the path into 'dir'
|
|
||||||
strncpy(dir, pathcopy, 1024);
|
|
||||||
dir[255]=0;
|
|
||||||
|
|
||||||
// copy the filename into 'fname'
|
|
||||||
strncpy(fname, slash+1, 128);
|
|
||||||
fname[128]=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dir[0] = 0;
|
|
||||||
|
|
||||||
strncpy(fname, pathcopy, 128);
|
|
||||||
fname[128]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used in findfile
|
|
||||||
int tolower(int c);
|
|
||||||
int strcasecmp(const char *s1, const char *s2){
|
|
||||||
while (*s1 != '\0' && tolower(*s1) == tolower(*s2))
|
|
||||||
{
|
|
||||||
s1++;
|
|
||||||
s2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy a TOC Entry from the CD native format to our tidier format
|
|
||||||
void TocEntryCopy(struct TocEntry* tocEntry, struct dirTocEntry* internalTocEntry){
|
|
||||||
int i;
|
|
||||||
int filenamelen;
|
|
||||||
|
|
||||||
tocEntry->fileSize = internalTocEntry->fileSize;
|
|
||||||
tocEntry->fileLBA = internalTocEntry->fileLBA;
|
|
||||||
tocEntry->fileProperties = internalTocEntry->fileProperties;
|
|
||||||
memcpy(tocEntry->date, internalTocEntry->dateStamp, 7);
|
|
||||||
|
|
||||||
if (CDVolDesc.filesystemType == 2){
|
|
||||||
// This is a Joliet Filesystem, so use Unicode to ISO string copy
|
|
||||||
|
|
||||||
filenamelen = internalTocEntry->filenameLength/2;
|
|
||||||
|
|
||||||
if (!(tocEntry->fileProperties & 0x02)){
|
|
||||||
// strip the ;1 from the filename
|
|
||||||
// filenamelen -= 2;//(Florin) nah, do not strip ;1
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i < filenamelen; i++)
|
|
||||||
tocEntry->filename[i] = internalTocEntry->filename[(i<<1)+1];
|
|
||||||
|
|
||||||
tocEntry->filename[filenamelen] = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
filenamelen = internalTocEntry->filenameLength;
|
|
||||||
|
|
||||||
if (!(tocEntry->fileProperties & 0x02)){
|
|
||||||
// strip the ;1 from the filename
|
|
||||||
// filenamelen -= 2;//(Florin) nah, do not strip ;1
|
|
||||||
}
|
|
||||||
|
|
||||||
// use normal string copy
|
|
||||||
strncpy(tocEntry->filename,internalTocEntry->filename,128);
|
|
||||||
tocEntry->filename[filenamelen] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a TOC Entry matches our extension list
|
|
||||||
int TocEntryCompare(char* filename, char* extensions){
|
|
||||||
static char ext_list[129];
|
|
||||||
|
|
||||||
char* token;
|
|
||||||
|
|
||||||
char* ext_point;
|
|
||||||
|
|
||||||
strncpy(ext_list,extensions,128);
|
|
||||||
ext_list[128]=0;
|
|
||||||
|
|
||||||
token = strtok( ext_list, " ," );
|
|
||||||
while( token != NULL )
|
|
||||||
{
|
|
||||||
// if 'token' matches extension of 'filename'
|
|
||||||
// then return a match
|
|
||||||
ext_point = strrchr(filename,'.');
|
|
||||||
|
|
||||||
if (strnicmp(ext_point, token, strlen(token)) == 0)
|
|
||||||
return (TRUE);
|
|
||||||
|
|
||||||
/* Get next token: */
|
|
||||||
token = strtok( NULL, " ," );
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not match found then return FALSE
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CD_SECS 60 /* seconds per minute */
|
|
||||||
#define CD_FRAMES 75 /* frames per second */
|
|
||||||
#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */
|
|
||||||
|
|
||||||
int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){
|
|
||||||
u32 i;
|
|
||||||
u8* buff;
|
|
||||||
int rmode;
|
|
||||||
|
|
||||||
switch (mode->datapattern) {
|
|
||||||
case CdSecS2048:
|
|
||||||
rmode = CDVD_MODE_2048; break;
|
|
||||||
case CdSecS2328:
|
|
||||||
rmode = CDVD_MODE_2328; break;
|
|
||||||
case CdSecS2340:
|
|
||||||
rmode = CDVD_MODE_2340; break;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<sectors; i++){
|
|
||||||
if (CDVDreadTrack(lsn+i, rmode)==-1)
|
|
||||||
return 0;
|
|
||||||
buff = CDVDgetBuffer();
|
|
||||||
if (buff==NULL) return 0;
|
|
||||||
|
|
||||||
switch (mode->datapattern){
|
|
||||||
case CdSecS2048:
|
|
||||||
memcpy((void*)((uptr)buf+2048*i), buff, 2048);break;//only data
|
|
||||||
case CdSecS2328:
|
|
||||||
memcpy((void*)((uptr)buf+2328*i), buff, 2328);break;//without sync & head & sub
|
|
||||||
case CdSecS2340:
|
|
||||||
memcpy((void*)((uptr)buf+2340*i), buff, 2340);break;//without sync
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DvdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){
|
|
||||||
u32 i;
|
|
||||||
u8* buff;
|
|
||||||
|
|
||||||
for (i=lsn; i<(lsn+sectors); i++){
|
|
||||||
if (CDVDreadTrack(i, CDVD_MODE_2048)==-1)
|
|
||||||
return 0;
|
|
||||||
buff = CDVDgetBuffer();
|
|
||||||
if (buff==NULL) return 0;
|
|
||||||
|
|
||||||
// switch (mode->datapattern){
|
|
||||||
// case CdSecS2064:
|
|
||||||
((u32*)buf)[0] = i + 0x30000;
|
|
||||||
memcpy((u8*)buf+12, buff, 2048);
|
|
||||||
(u8*)buf+= 2064; break;
|
|
||||||
// default:
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
* The functions below are not exported for normal file-system *
|
|
||||||
* operations, but are used by the file-system operations, and *
|
|
||||||
* may also be exported for use via RPC *
|
|
||||||
**************************************************************/
|
|
||||||
|
|
||||||
int CDVD_GetVolumeDescriptor(void){
|
|
||||||
// Read until we find the last valid Volume Descriptor
|
|
||||||
int volDescSector;
|
|
||||||
|
|
||||||
static struct cdVolDesc localVolDesc;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("CDVD_GetVolumeDescriptor called\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (volDescSector = 16; volDescSector<20; volDescSector++)
|
|
||||||
{
|
|
||||||
CdRead(volDescSector,1,&localVolDesc,&cdReadMode);
|
|
||||||
// CdSync(0x00);
|
|
||||||
|
|
||||||
// If this is still a volume Descriptor
|
|
||||||
if (strncmp(localVolDesc.volID, "CD001", 5) == 0)
|
|
||||||
{
|
|
||||||
if ((localVolDesc.filesystemType == 1) ||
|
|
||||||
(localVolDesc.filesystemType == 2))
|
|
||||||
{
|
|
||||||
memcpy(&CDVolDesc, &localVolDesc, sizeof(struct cdVolDesc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CDVolDesc.filesystemType == 1)
|
|
||||||
printf("CD FileSystem is ISO9660\n");
|
|
||||||
else if (CDVolDesc.filesystemType == 2)
|
|
||||||
printf("CD FileSystem is Joliet\n");
|
|
||||||
else printf("Could not detect CD FileSystem type\n");
|
|
||||||
#endif
|
|
||||||
// CdStop();
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CDVD_findfile(char* fname, struct TocEntry* tocEntry){
|
|
||||||
static char filename[128+1];
|
|
||||||
static char pathname[1024+1];
|
|
||||||
static char toc[2048];
|
|
||||||
char* dirname;
|
|
||||||
|
|
||||||
|
|
||||||
static struct TocEntry localTocEntry; // used for internal checking only
|
|
||||||
|
|
||||||
int found_dir;
|
|
||||||
|
|
||||||
int num_dir_sectors;
|
|
||||||
int current_sector;
|
|
||||||
|
|
||||||
int dir_lba;
|
|
||||||
|
|
||||||
struct dirTocEntry* tocEntryPointer;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("CDVD_findfile called\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//make sure we have good cdReadMode
|
|
||||||
cdReadMode.trycount = 0;
|
|
||||||
cdReadMode.spindlctrl = CdSpinStm;
|
|
||||||
cdReadMode.datapattern = CdSecS2048;
|
|
||||||
|
|
||||||
_splitpath2(fname, pathname, filename);
|
|
||||||
|
|
||||||
// Find the TOC for a specific directory
|
|
||||||
if (CDVD_GetVolumeDescriptor() != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("Could not get CD Volume Descriptor\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the TOC of the root directory
|
|
||||||
if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
// point the tocEntryPointer at the first real toc entry
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
|
|
||||||
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix
|
|
||||||
current_sector = tocEntryPointer->fileLBA;
|
|
||||||
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
|
|
||||||
|
|
||||||
localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA;
|
|
||||||
// while (there are more dir names in the path)
|
|
||||||
dirname = strtok( pathname, "\\/" );
|
|
||||||
|
|
||||||
while( dirname != NULL )
|
|
||||||
{
|
|
||||||
found_dir = FALSE;
|
|
||||||
/*
|
|
||||||
while(tocEntryPointer->length > 0)
|
|
||||||
{
|
|
||||||
// while there are still more directory entries then search through
|
|
||||||
// for the one we want
|
|
||||||
|
|
||||||
if (tocEntryPointer->fileProperties & 0x02)
|
|
||||||
{
|
|
||||||
// Copy the CD format TOC Entry to our format
|
|
||||||
TocEntryCopy(&localTocEntry, tocEntryPointer);
|
|
||||||
|
|
||||||
// If this TOC Entry is a directory,
|
|
||||||
// then see if it has the right name
|
|
||||||
if (strcasecmp(dirname,localTocEntry.filename) == 0)
|
|
||||||
{
|
|
||||||
// if the name matches then we've found the directory
|
|
||||||
found_dir = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// point to the next entry
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048))
|
|
||||||
{
|
|
||||||
num_dir_sectors--;
|
|
||||||
|
|
||||||
if (num_dir_sectors > 0)
|
|
||||||
{
|
|
||||||
// If we've run out of entries, but arent on the last sector
|
|
||||||
// then load another sector
|
|
||||||
|
|
||||||
current_sector++;
|
|
||||||
if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// CdSync(0x00);
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Couldnt find the directory, and got to end of directory
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (tocEntryPointer->fileProperties & 0x02)
|
|
||||||
{
|
|
||||||
TocEntryCopy(&localTocEntry, tocEntryPointer);
|
|
||||||
|
|
||||||
// If this TOC Entry is a directory,
|
|
||||||
// then see if it has the right name
|
|
||||||
if (strcmp(dirname,localTocEntry.filename) == 0)
|
|
||||||
{
|
|
||||||
// if the name matches then we've found the directory
|
|
||||||
found_dir = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// point to the next entry
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we havent found the directory name we wanted then fail
|
|
||||||
if (found_dir != TRUE)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get next directory name
|
|
||||||
dirname = strtok( NULL, "\\/" );
|
|
||||||
|
|
||||||
// Read the TOC of the found subdirectory
|
|
||||||
if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// CdSync(0x00);
|
|
||||||
|
|
||||||
num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; //round up fix
|
|
||||||
current_sector = localTocEntry.fileLBA;
|
|
||||||
|
|
||||||
// and point the tocEntryPointer at the first real toc entry
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
|
|
||||||
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix
|
|
||||||
dir_lba = tocEntryPointer->fileLBA;
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
|
|
||||||
while (num_dir_sectors > 0)
|
|
||||||
{
|
|
||||||
while(tocEntryPointer->length != 0)
|
|
||||||
{
|
|
||||||
// Copy the CD format TOC Entry to our format
|
|
||||||
TocEntryCopy(&localTocEntry, tocEntryPointer);
|
|
||||||
|
|
||||||
if ((strnicmp(localTocEntry.filename, filename, strlen(filename)) == 0) ||
|
|
||||||
((filename[strlen(filename)-2] == ';') &&
|
|
||||||
(localTocEntry.filename[strlen(localTocEntry.filename)-2] == ';') &&
|
|
||||||
(strnicmp(localTocEntry.filename, filename, strlen(filename)-2) == 0)))
|
|
||||||
{
|
|
||||||
// if the filename matches then copy the toc Entry
|
|
||||||
tocEntry->fileLBA = localTocEntry.fileLBA;
|
|
||||||
tocEntry->fileProperties = localTocEntry.fileProperties;
|
|
||||||
tocEntry->fileSize = localTocEntry.fileSize;
|
|
||||||
|
|
||||||
strcpy(tocEntry->filename, localTocEntry.filename);
|
|
||||||
memcpy(tocEntry->date, localTocEntry.date, 7);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("CDVD_findfile: found file\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_dir_sectors--;
|
|
||||||
|
|
||||||
if (num_dir_sectors > 0)
|
|
||||||
{
|
|
||||||
dir_lba++;
|
|
||||||
|
|
||||||
if (CdRead(dir_lba,1,toc,&cdReadMode) != TRUE){
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// CdSync(0x00);
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the RPC-ready function which takes the request to start the tocEntry retrieval
|
|
||||||
int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs){
|
|
||||||
// int dir_depth = 1;
|
|
||||||
static char toc[2048];
|
|
||||||
char* dirname;
|
|
||||||
int found_dir;
|
|
||||||
int num_dir_sectors;
|
|
||||||
unsigned int toc_entry_num;
|
|
||||||
struct dirTocEntry* tocEntryPointer;
|
|
||||||
static struct TocEntry localTocEntry;
|
|
||||||
int current_sector;
|
|
||||||
|
|
||||||
// store the extension list statically for the retrieve function
|
|
||||||
strncpy(getDirTocData.extension_list, extensions, 128);
|
|
||||||
getDirTocData.extension_list[128]=0;
|
|
||||||
|
|
||||||
getDirTocData.inc_dirs = inc_dirs;
|
|
||||||
|
|
||||||
// Find the TOC for a specific directory
|
|
||||||
if (CDVD_GetVolumeDescriptor() != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"\n", pathname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Read the TOC of the root directory
|
|
||||||
if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC: ] Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
// point the tocEntryPointer at the first real toc entry
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
|
|
||||||
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11;
|
|
||||||
current_sector = tocEntryPointer->fileLBA;
|
|
||||||
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
|
|
||||||
// use strtok to get the next dir name
|
|
||||||
|
|
||||||
// if there isnt one, then assume we want the LBA
|
|
||||||
// for the current one, and exit the while loop
|
|
||||||
|
|
||||||
// if there is another dir name then increment dir_depth
|
|
||||||
// and look through dir table entries until we find the right name
|
|
||||||
// if we dont find the right name
|
|
||||||
// before finding an entry at a higher level (lower num), then return nothing
|
|
||||||
|
|
||||||
localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA;
|
|
||||||
|
|
||||||
// while (there are more dir names in the path)
|
|
||||||
dirname = strtok( pathname, "\\/" );
|
|
||||||
while( dirname != NULL ){
|
|
||||||
found_dir = FALSE;
|
|
||||||
|
|
||||||
while(1){
|
|
||||||
if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) {
|
|
||||||
num_dir_sectors--;
|
|
||||||
|
|
||||||
if (num_dir_sectors > 0){
|
|
||||||
// If we've run out of entries, but arent on the last sector
|
|
||||||
// then load another sector
|
|
||||||
|
|
||||||
current_sector++;
|
|
||||||
if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC: ] Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
// Couldnt find the directory, and got to end of directory
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tocEntryPointer->fileProperties & 0x02){
|
|
||||||
TocEntryCopy(&localTocEntry, tocEntryPointer);
|
|
||||||
|
|
||||||
// If this TOC Entry is a directory,
|
|
||||||
// then see if it has the right name
|
|
||||||
if (strcmp(dirname,localTocEntry.filename) == 0){
|
|
||||||
// if the name matches then we've found the directory
|
|
||||||
found_dir = TRUE;
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d\n",dirname,current_sector);
|
|
||||||
RPC_LOG("[RPC: ] LBA of found subdirectory = %d\n",localTocEntry.fileLBA);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// point to the next entry
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we havent found the directory name we wanted then fail
|
|
||||||
if (found_dir != TRUE)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Get next directory name
|
|
||||||
dirname = strtok( NULL, "\\/" );
|
|
||||||
|
|
||||||
// Read the TOC of the found subdirectory
|
|
||||||
if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC: ] Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
num_dir_sectors = (localTocEntry.fileSize+2047) >> 11;
|
|
||||||
current_sector = localTocEntry.fileLBA;
|
|
||||||
|
|
||||||
// and point the tocEntryPointer at the first real toc entry
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We know how much data we need to read in from the DirTocHeader
|
|
||||||
// but we need to read in at least 1 sector before we can get this value
|
|
||||||
|
|
||||||
// Now we need to COUNT the number of entries (dont do anything with info at this point)
|
|
||||||
// so set the tocEntryPointer to point to the first actual file entry
|
|
||||||
|
|
||||||
// This is a bit of a waste of reads since we're not actually copying the data out yet,
|
|
||||||
// but we dont know how big this TOC might be, so we cant allocate a specific size
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
|
|
||||||
// Need to STORE the start LBA and number of Sectors, for use by the retrieve func.
|
|
||||||
getDirTocData.start_LBA = localTocEntry.fileLBA;
|
|
||||||
getDirTocData.num_sectors = (tocEntryPointer->fileSize+2047) >> 11;
|
|
||||||
getDirTocData.num_entries = 0;
|
|
||||||
getDirTocData.current_entry = 0;
|
|
||||||
getDirTocData.current_sector = getDirTocData.start_LBA;
|
|
||||||
getDirTocData.current_sector_offset = 0;
|
|
||||||
|
|
||||||
num_dir_sectors = getDirTocData.num_sectors;
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
|
|
||||||
toc_entry_num=0;
|
|
||||||
|
|
||||||
while(1){
|
|
||||||
if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)){
|
|
||||||
// decrease the number of dirs remaining
|
|
||||||
num_dir_sectors--;
|
|
||||||
|
|
||||||
if (num_dir_sectors > 0){
|
|
||||||
// If we've run out of entries, but arent on the last sector
|
|
||||||
// then load another sector
|
|
||||||
getDirTocData.current_sector++;
|
|
||||||
|
|
||||||
if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC: ] Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getDirTocData.num_entries = toc_entry_num;
|
|
||||||
getDirTocData.current_sector = getDirTocData.start_LBA;
|
|
||||||
return (toc_entry_num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We've found a file/dir in this directory
|
|
||||||
// now check if it matches our extension list (if there is one)
|
|
||||||
TocEntryCopy(&localTocEntry, tocEntryPointer);
|
|
||||||
|
|
||||||
if (localTocEntry.fileProperties & 0x02){
|
|
||||||
// If this is a subdir, then check if we want to include subdirs
|
|
||||||
if (getDirTocData.inc_dirs){
|
|
||||||
toc_entry_num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (strlen(getDirTocData.extension_list) > 0){
|
|
||||||
if (TocEntryCompare(localTocEntry.filename, getDirTocData.extension_list) == TRUE){
|
|
||||||
// increment the number of matching entries counter
|
|
||||||
toc_entry_num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
toc_entry_num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// THIS SHOULD BE UNREACHABLE -
|
|
||||||
// since we are trying to count ALL matching entries, rather than upto a limit
|
|
||||||
|
|
||||||
|
|
||||||
// STORE total number of TOC entries
|
|
||||||
getDirTocData.num_entries = toc_entry_num;
|
|
||||||
getDirTocData.current_sector = getDirTocData.start_LBA;
|
|
||||||
|
|
||||||
|
|
||||||
// we've reached the toc entry limit, so return how many we've done
|
|
||||||
return (toc_entry_num);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function can be called repeatedly after CDVD_GetDir_RPC_request to get the actual entries
|
|
||||||
// buffer (tocEntry) must be 18KB in size, and this will be filled with a maximum of 128 entries in one go
|
|
||||||
int CDVD_GetDir_RPC_get_entries(struct TocEntry tocEntry[], int req_entries){
|
|
||||||
static char toc[2048];
|
|
||||||
int toc_entry_num;
|
|
||||||
|
|
||||||
struct dirTocEntry* tocEntryPointer;
|
|
||||||
|
|
||||||
if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
if (getDirTocData.current_entry == 0){
|
|
||||||
// if this is the first read then make sure we point to the first real entry
|
|
||||||
(char*)tocEntryPointer = toc;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer += tocEntryPointer->length;
|
|
||||||
|
|
||||||
getDirTocData.current_sector_offset = (char*)tocEntryPointer - toc;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req_entries > 128)
|
|
||||||
req_entries = 128;
|
|
||||||
|
|
||||||
for (toc_entry_num=0; toc_entry_num < req_entries;){
|
|
||||||
if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048)){
|
|
||||||
// decrease the number of dirs remaining
|
|
||||||
getDirTocData.num_sectors--;
|
|
||||||
|
|
||||||
if (getDirTocData.num_sectors > 0){
|
|
||||||
// If we've run out of entries, but arent on the last sector
|
|
||||||
// then load another sector
|
|
||||||
getDirTocData.current_sector++;
|
|
||||||
|
|
||||||
if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//CdSync(0x00);
|
|
||||||
|
|
||||||
getDirTocData.current_sector_offset = 0;
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return (toc_entry_num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This must be incremented even if the filename doesnt match extension list
|
|
||||||
getDirTocData.current_entry++;
|
|
||||||
|
|
||||||
// We've found a file in this directory
|
|
||||||
// now check if it matches our extension list (if there is one)
|
|
||||||
|
|
||||||
// Copy the entry regardless, as it makes the comparison easier
|
|
||||||
// if it doesn't match then it will just be overwritten
|
|
||||||
TocEntryCopy(&tocEntry[toc_entry_num], tocEntryPointer);
|
|
||||||
|
|
||||||
if (tocEntry[toc_entry_num].fileProperties & 0x02){
|
|
||||||
// If this is a subdir, then check if we want to include subdirs
|
|
||||||
if (getDirTocData.inc_dirs) {
|
|
||||||
toc_entry_num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirTocData.current_sector_offset += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (strlen(getDirTocData.extension_list) > 0){
|
|
||||||
if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE){
|
|
||||||
// increment the number of matching entries counter
|
|
||||||
toc_entry_num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirTocData.current_sector_offset += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
toc_entry_num++;
|
|
||||||
getDirTocData.current_sector_offset += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (strlen(getDirTocData.extension_list) > 0)
|
|
||||||
{
|
|
||||||
if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE)
|
|
||||||
{
|
|
||||||
|
|
||||||
// increment this here, rather than in the main for loop
|
|
||||||
// since this should count the number of matching entries
|
|
||||||
toc_entry_num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirTocData.current_sector_offset += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toc_entry_num++;
|
|
||||||
getDirTocData.current_sector_offset += tocEntryPointer->length;
|
|
||||||
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
return (toc_entry_num);
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
|
|
||||||
* Modified by Florin for PCSX2 emu
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CDVDISO_H__
|
|
||||||
#define __CDVDISO_H__
|
|
||||||
|
|
||||||
#include "CDVDlib.h"
|
|
||||||
|
|
||||||
int CDVD_findfile(char* fname, struct TocEntry* tocEntry);
|
|
||||||
int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs);
|
|
||||||
int CDVD_GetDir_RPC_get_entries(struct TocEntry tocEntry[], int req_entries);
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct rootDirTocHeader
|
|
||||||
{
|
|
||||||
u16 length; //+00
|
|
||||||
u32 tocLBA; //+02
|
|
||||||
u32 tocLBA_bigend; //+06
|
|
||||||
u32 tocSize; //+0A
|
|
||||||
u32 tocSize_bigend; //+0E
|
|
||||||
u8 dateStamp[8]; //+12
|
|
||||||
u8 reserved[6]; //+1A
|
|
||||||
u8 reserved2; //+20
|
|
||||||
u8 reserved3; //+21
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
}; //+22
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct asciiDate
|
|
||||||
{
|
|
||||||
char year[4];
|
|
||||||
char month[2];
|
|
||||||
char day[2];
|
|
||||||
char hours[2];
|
|
||||||
char minutes[2];
|
|
||||||
char seconds[2];
|
|
||||||
char hundreths[2];
|
|
||||||
char terminator[1];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct cdVolDesc
|
|
||||||
{
|
|
||||||
u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL
|
|
||||||
u8 volID[5]; // "CD001"
|
|
||||||
u8 reserved2;
|
|
||||||
u8 reserved3;
|
|
||||||
u8 sysIdName[32];
|
|
||||||
u8 volName[32]; // The ISO9660 Volume Name
|
|
||||||
u8 reserved5[8];
|
|
||||||
u32 volSize; // Volume Size
|
|
||||||
u32 volSizeBig; // Volume Size Big-Endian
|
|
||||||
u8 reserved6[32];
|
|
||||||
u32 unknown1;
|
|
||||||
u32 unknown1_bigend;
|
|
||||||
u16 volDescSize; //+80
|
|
||||||
u16 volDescSize_bigend; //+82
|
|
||||||
u32 unknown3; //+84
|
|
||||||
u32 unknown3_bigend; //+88
|
|
||||||
u32 priDirTableLBA; // LBA of Primary Dir Table //+8C
|
|
||||||
u32 reserved7; //+90
|
|
||||||
u32 secDirTableLBA; // LBA of Secondary Dir Table //+94
|
|
||||||
u32 reserved8; //+98
|
|
||||||
struct rootDirTocHeader rootToc;
|
|
||||||
u8 volSetName[128];
|
|
||||||
u8 publisherName[128];
|
|
||||||
u8 preparerName[128];
|
|
||||||
u8 applicationName[128];
|
|
||||||
u8 copyrightFileName[37];
|
|
||||||
u8 abstractFileName[37];
|
|
||||||
u8 bibliographyFileName[37];
|
|
||||||
struct asciiDate creationDate;
|
|
||||||
struct asciiDate modificationDate;
|
|
||||||
struct asciiDate effectiveDate;
|
|
||||||
struct asciiDate expirationDate;
|
|
||||||
u8 reserved10;
|
|
||||||
u8 reserved11[1166];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct dirTableEntry
|
|
||||||
{
|
|
||||||
u8 dirNameLength;
|
|
||||||
u8 reserved;
|
|
||||||
u32 dirTOCLBA;
|
|
||||||
u16 dirDepth;
|
|
||||||
u8 dirName[32];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct dirTocEntry
|
|
||||||
{
|
|
||||||
short length;
|
|
||||||
unsigned int fileLBA;
|
|
||||||
unsigned int fileLBA_bigend;
|
|
||||||
unsigned int fileSize;
|
|
||||||
unsigned int fileSize_bigend;
|
|
||||||
unsigned char dateStamp[6];
|
|
||||||
unsigned char reserved1;
|
|
||||||
unsigned char fileProperties;
|
|
||||||
unsigned char reserved2[6];
|
|
||||||
unsigned char filenameLength;
|
|
||||||
unsigned char filename[128];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif // This is the internal format on the CD
|
|
||||||
// TocEntry structure contains only the important stuff needed for export
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif//__CDVDISO_H__
|
|
|
@ -1,264 +0,0 @@
|
||||||
/*
|
|
||||||
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
|
|
||||||
* Modified by Florin for PCSX2 emu
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "CDVDlib.h"
|
|
||||||
#include "CDVDiso.h"
|
|
||||||
#include "CDVDisodrv.h"
|
|
||||||
|
|
||||||
CdRMode cdReadMode;
|
|
||||||
|
|
||||||
struct fdtable{
|
|
||||||
//int fd;
|
|
||||||
int fileSize;
|
|
||||||
int LBA;
|
|
||||||
int filePos;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct fdtable fd_table[16];
|
|
||||||
static int fd_used[16];
|
|
||||||
static int files_open=0;
|
|
||||||
static int inited=FALSE;
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* The functions below are the normal file-system operations, *
|
|
||||||
* used to provide a standard filesystem interface *
|
|
||||||
*************************************************************/
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CDVDFS_init
|
|
||||||
// called by 80000592 sceCdInit()
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
void CDVDFS_init(){
|
|
||||||
|
|
||||||
if (inited) return;//might change in the future as a param; forceInit/Reset
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:init] CDVD Filesystem v1.00\n");
|
|
||||||
RPC_LOG("[CDVDisodrv ] \tby A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)\n");
|
|
||||||
RPC_LOG("[CDVDisodrv ] Initializing '%s' file driver.\n", "cdfs");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//CdInit(0); already called by plugin loading system ;)
|
|
||||||
|
|
||||||
cdReadMode.trycount = 0;
|
|
||||||
cdReadMode.spindlctrl = CdSpinStm;
|
|
||||||
cdReadMode.datapattern = CdSecS2048; //isofs driver only needs
|
|
||||||
//2KB sectors
|
|
||||||
|
|
||||||
memset(fd_table, 0, sizeof(fd_table));
|
|
||||||
memset(fd_used, 0, 16*sizeof(int));
|
|
||||||
|
|
||||||
inited = TRUE;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CDVDFS_open
|
|
||||||
// called by 80000001 fileio_open for devices: "cdrom:", "cdrom0:"
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
int CDVDFS_open(char *name, int mode){
|
|
||||||
register int j;
|
|
||||||
static struct TocEntry tocEntry;
|
|
||||||
|
|
||||||
// check if the file exists
|
|
||||||
if (CDVD_findfile(name, &tocEntry) != TRUE)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(mode != 1) return -2; //SCE_RDONLY
|
|
||||||
|
|
||||||
// set up a new file descriptor
|
|
||||||
for(j=0; j < 16; j++) if(fd_used[j] == 0) break;
|
|
||||||
if(j >= 16) return -3;
|
|
||||||
|
|
||||||
fd_used[j] = 1;
|
|
||||||
files_open++;
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:open] internal fd=%d\n", j);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fd_table[j].fileSize = tocEntry.fileSize;
|
|
||||||
fd_table[j].LBA = tocEntry.fileLBA;
|
|
||||||
fd_table[j].filePos = 0;
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv ] tocEntry.fileSize = %d\n",tocEntry.fileSize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CDVDFS_lseek
|
|
||||||
// called by 80000001 fileio_lseek for devices: "cdrom:", "cdrom0:"
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
int CDVDFS_lseek(int fd, int offset, int whence){
|
|
||||||
|
|
||||||
if ((fd >= 16) || (fd_used[fd]==0)){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:lseek] ERROR: File does not appear to be open!\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(whence){
|
|
||||||
case SEEK_SET:
|
|
||||||
fd_table[fd].filePos = offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEEK_CUR:
|
|
||||||
fd_table[fd].filePos += offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEEK_END:
|
|
||||||
fd_table[fd].filePos = fd_table[fd].fileSize + offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd_table[fd].filePos < 0)
|
|
||||||
fd_table[fd].filePos = 0;
|
|
||||||
|
|
||||||
if (fd_table[fd].filePos > fd_table[fd].fileSize)
|
|
||||||
fd_table[fd].filePos = fd_table[fd].fileSize;
|
|
||||||
|
|
||||||
return fd_table[fd].filePos;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CDVDFS_read
|
|
||||||
// called by 80000001 fileio_read for devices: "cdrom:", "cdrom0:", "cdfs:"
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
int CDVDFS_read( int fd, char *buffer, int size ){
|
|
||||||
// int start_sector;
|
|
||||||
int off_sector;
|
|
||||||
// int num_sectors;
|
|
||||||
|
|
||||||
//static char local_buffer[2024*2048]; //4MB
|
|
||||||
static char lb[2048]; //2KB
|
|
||||||
//Start, Aligned, End
|
|
||||||
int ssector, asector, esector;
|
|
||||||
int ssize=0, asize, esize;
|
|
||||||
|
|
||||||
if ((fd >= 16) || (fd_used[fd]==0)){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:read] ERROR: File does not appear to be open!\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A few sanity checks
|
|
||||||
if (fd_table[fd].filePos > fd_table[fd].fileSize){
|
|
||||||
// We cant start reading from past the beginning of the file
|
|
||||||
return 0; // File exists but we couldnt read anything from it
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fd_table[fd].filePos + size) > fd_table[fd].fileSize)
|
|
||||||
size = fd_table[fd].fileSize - fd_table[fd].filePos;
|
|
||||||
|
|
||||||
// Now work out where we want to start reading from
|
|
||||||
asector = ssector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11);
|
|
||||||
off_sector = (fd_table[fd].filePos & 0x7FF);
|
|
||||||
if (off_sector){
|
|
||||||
ssize = min(2048 - off_sector, size);
|
|
||||||
size -= ssize;
|
|
||||||
asector++;
|
|
||||||
}
|
|
||||||
asize = size & 0xFFFFF800;
|
|
||||||
esize = size & 0x000007FF;
|
|
||||||
esector=asector + (asize >> 11);
|
|
||||||
size += ssize;
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X\n", ssector, esector-(esize==0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ssize){ if (CdRead(ssector, 1, lb, &cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(buffer, lb + off_sector, ssize);
|
|
||||||
}
|
|
||||||
if (asize) if (CdRead(asector, asize >> 11, buffer+ssize, &cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (esize){ if (CdRead(esector, 1, lb, &cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(buffer+ssize+asize, lb, esize);
|
|
||||||
}
|
|
||||||
/***********************
|
|
||||||
// Now work out where we want to start reading from
|
|
||||||
start_sector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11);
|
|
||||||
off_sector = (fd_table[fd].filePos & 0x7FF);
|
|
||||||
num_sectors = ((off_sector + size) >> 11) + 1;
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X\n",start_sector,start_sector+num_sectors);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Read the data (we only ever get 16KB max request at once)
|
|
||||||
if (CdRead(start_sector, num_sectors, local_buffer, &cdReadMode) != TRUE){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
//RPC_LOG("sector = %d, start sector = %d\n",sector,start_sector);
|
|
||||||
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//CdSync(0); hm, a wait function maybe...
|
|
||||||
|
|
||||||
memcpy(buffer,local_buffer+off_sector,size);
|
|
||||||
**************************/
|
|
||||||
fd_table[fd].filePos += size;
|
|
||||||
|
|
||||||
return (size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CDVDFS_write
|
|
||||||
// called by 80000001 fileio_write for devices: "cdrom:", "cdrom0:"
|
|
||||||
// hehe, this ain't a CD writing option :D
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
int CDVDFS_write( int fd, char * buffer, int size ){
|
|
||||||
if(size == 0) return 0;
|
|
||||||
else return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CDVDFS_close
|
|
||||||
// called by 80000001 fileio_close for devices: "cdrom:", "cdrom0:"
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
int CDVDFS_close( int fd){
|
|
||||||
|
|
||||||
if ((fd >= 16) || (fd_used[fd]==0)){
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:close] ERROR: File does not appear to be open!\n");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RPC_LOG
|
|
||||||
RPC_LOG("[CDVDisodrv:close] internal fd %d\n", fd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fd_used[fd] = 0;
|
|
||||||
files_open--;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*
|
|
||||||
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
|
|
||||||
* Modified by Florin for PCSX2 emu
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CDVDISODRV_H__
|
|
||||||
#define __CDVDISODRV_H__
|
|
||||||
|
|
||||||
//#include "Common.h"
|
|
||||||
#include "CDVDlib.h"
|
|
||||||
|
|
||||||
extern CdRMode cdReadMode;
|
|
||||||
|
|
||||||
/* Filing-system exported functions */
|
|
||||||
void CDVDFS_init();
|
|
||||||
int CDVDFS_open(char *name, int mode);
|
|
||||||
int CDVDFS_lseek(int fd, int offset, int whence);
|
|
||||||
int CDVDFS_read( int fd, char * buffer, int size );
|
|
||||||
int CDVDFS_write( int fd, char * buffer, int size );
|
|
||||||
int CDVDFS_close( int fd);
|
|
||||||
|
|
||||||
#endif//__CDVDISODRV_H__
|
|
|
@ -1,189 +0,0 @@
|
||||||
/*
|
|
||||||
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
|
|
||||||
* Linux kernel headers
|
|
||||||
* Modified by Florin for PCSX2 emu
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CDVDLIB_H
|
|
||||||
#define _CDVDLIB_H
|
|
||||||
|
|
||||||
#define __WIN32__
|
|
||||||
#define __MSCW32__
|
|
||||||
#define CDVDdefs
|
|
||||||
#include "PS2Etypes.h"
|
|
||||||
#include "PS2Edefs.h"
|
|
||||||
|
|
||||||
// Macros for READ Data pattan
|
|
||||||
#define CdSecS2048 0 // sector size 2048
|
|
||||||
#define CdSecS2328 1 // sector size 2328
|
|
||||||
#define CdSecS2340 2 // sector size 2340
|
|
||||||
|
|
||||||
//#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
|
|
||||||
//#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
|
|
||||||
//#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
|
|
||||||
//#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */
|
|
||||||
//#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
|
|
||||||
* 2340, or 2352 bytes long.
|
|
||||||
* Sector types of the standard CD-ROM data formats:
|
|
||||||
*
|
|
||||||
* format sector type user data size (bytes)
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* 1 (Red Book) CD-DA 2352 (CD_FRAMESIZE_RAW)
|
|
||||||
* 2 (Yellow Book) Mode1 Form1 2048 (CD_FRAMESIZE)
|
|
||||||
* 3 (Yellow Book) Mode1 Form2 2336 (CD_FRAMESIZE_RAW0)
|
|
||||||
* 4 (Green Book) Mode2 Form1 2048 (CD_FRAMESIZE)
|
|
||||||
* 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The layout of the standard CD-ROM data formats:
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
* - audio (red): | audio_sample_bytes |
|
|
||||||
* | 2352 |
|
|
||||||
*
|
|
||||||
* - data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
|
|
||||||
* | 12 - 4 - 2048 - 4 - 8 - 276 |
|
|
||||||
*
|
|
||||||
* - data (yellow, mode2): | sync - head - data |
|
|
||||||
* | 12 - 4 - 2336 |
|
|
||||||
*
|
|
||||||
* - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
|
|
||||||
* | 12 - 4 - 8 - 2048 - 4 - 276 |
|
|
||||||
*
|
|
||||||
* - XA data (green, mode2 form2): | sync - head - sub - data - Spare |
|
|
||||||
* | 12 - 4 - 8 - 2324 - 4 |
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Macros for Spindle control
|
|
||||||
#define CdSpinMax 0
|
|
||||||
#define CdSpinNom 1 // Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced.
|
|
||||||
#define CdSpinStm 0 // Recommended stream rotation speed.
|
|
||||||
|
|
||||||
// Macros for TrayReq
|
|
||||||
#define CdTrayOpen 0
|
|
||||||
#define CdTrayClose 1
|
|
||||||
#define CdTrayCheck 2
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros for sceCdGetDiskType() //comments translated from japanese;)
|
|
||||||
*/
|
|
||||||
#define SCECdIllgalMedia 0xff
|
|
||||||
/* ILIMEDIA (Illegal Media)
|
|
||||||
A non-PS / non-PS2 Disc. */
|
|
||||||
#define SCECdDVDV 0xfe
|
|
||||||
/* DVDV (DVD Video)
|
|
||||||
A non-PS / non-PS2 Disc, but a DVD Video Disc */
|
|
||||||
#define SCECdCDDA 0xfd
|
|
||||||
/* CDDA (CD DA)
|
|
||||||
A non-PS / non-PS2 Disc that include a DA track */
|
|
||||||
#define SCECdPS2DVD 0x14
|
|
||||||
/* PS2DVD PS2 consumer DVD. */
|
|
||||||
#define SCECdPS2CDDA 0x13
|
|
||||||
/* PS2CDDA PS2 consumer CD that includes a DA track */
|
|
||||||
#define SCECdPS2CD 0x12
|
|
||||||
/* PS2CD PS2 consumer CD that does not include a DA track */
|
|
||||||
#define SCECdPSCDDA 0x11
|
|
||||||
/* PSCDDA PS CD that includes a DA track */
|
|
||||||
#define SCECdPSCD 0x10
|
|
||||||
/* PSCD PS CD that does not include a DA track */
|
|
||||||
#define SCECdDETCT 0x01
|
|
||||||
/* DETCT (Detecting) Disc distinction action */
|
|
||||||
#define SCECdNODISC 0x00
|
|
||||||
/* NODISC (No disc) No disc entered */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Media mode
|
|
||||||
*/
|
|
||||||
#define SCECdCD 1
|
|
||||||
#define SCECdDVD 2
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 stat; // 0: normal. Any other: error
|
|
||||||
u8 second; // second (BCD value)
|
|
||||||
u8 minute; // minute (BCD value)
|
|
||||||
u8 hour; // hour (BCD value)
|
|
||||||
u8 week; // week (BCD value)
|
|
||||||
u8 day; // day (BCD value)
|
|
||||||
u8 month; // month (BCD value)
|
|
||||||
u8 year; // year (BCD value)
|
|
||||||
} CdCLOCK;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u32 lsn; // Logical sector number of file
|
|
||||||
u32 size; // File size (in bytes)
|
|
||||||
char name[16]; // Filename
|
|
||||||
u8 date[8]; // 1th: Seconds
|
|
||||||
// 2th: Minutes
|
|
||||||
// 3th: Hours
|
|
||||||
// 4th: Date
|
|
||||||
// 5th: Month
|
|
||||||
// 6th 7th: Year (4 digits)
|
|
||||||
} CdlFILE;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 minute; // Minutes
|
|
||||||
u8 second; // Seconds
|
|
||||||
u8 sector; // Sector
|
|
||||||
u8 track; // Track number
|
|
||||||
} CdlLOCCD;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 trycount; // Read try count (No. of error retries + 1) (0 - 255)
|
|
||||||
u8 spindlctrl; // SCECdSpinStm: Recommended stream rotation speed.
|
|
||||||
// SCECdSpinNom: Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced.
|
|
||||||
u8 datapattern; // SCECdSecS2048: Data size 2048 bytes
|
|
||||||
// SCECdSecS2328: 2328 bytes
|
|
||||||
// SCECdSecS2340: 2340 bytes
|
|
||||||
u8 pad; // Padding data produced by alignment.
|
|
||||||
} CdRMode;
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct TocEntry
|
|
||||||
{
|
|
||||||
u32 fileLBA;
|
|
||||||
u32 fileSize;
|
|
||||||
u8 fileProperties;
|
|
||||||
u8 padding1[3];
|
|
||||||
u8 filename[128+1];
|
|
||||||
u8 date[7];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int CDVD_findfile(char* fname, struct TocEntry* tocEntry);
|
|
||||||
/*
|
|
||||||
int CdBreak(void);
|
|
||||||
int CdCallback( void (*func)() );
|
|
||||||
int CdDiskReady(int mode);
|
|
||||||
int CdGetDiskType(void);
|
|
||||||
int CdGetError(void);
|
|
||||||
u32 CdGetReadPos(void);
|
|
||||||
int CdGetToc(u8 *toc);
|
|
||||||
int CdInit(int init_mode);
|
|
||||||
CdlLOCCD *CdIntToPos(int i, CdlLOCCD *p);
|
|
||||||
int CdPause(void);
|
|
||||||
int CdPosToInt(CdlLOCCD *p);*/
|
|
||||||
int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode);
|
|
||||||
int DvdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode);
|
|
||||||
/*int CdReadClock(CdCLOCK *rtc);
|
|
||||||
int CdSearchFile (CdlFILE *fp, const char *name);
|
|
||||||
int CdSeek(u32 lsn);
|
|
||||||
int CdStandby(void);
|
|
||||||
int CdStatus(void);
|
|
||||||
int CdStop(void);
|
|
||||||
int CdSync(int mode);
|
|
||||||
int CdTrayReq(int mode, u32 *traycnt);
|
|
||||||
*/
|
|
||||||
#endif // _CDVDLIB_H
|
|
|
@ -1,3 +0,0 @@
|
||||||
del *.o
|
|
||||||
del *.c~
|
|
||||||
del *.h~
|
|
|
@ -1,935 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cdr.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/12/25 - Pete
|
|
||||||
// - added an hack in CDVDgetTD for big dvds
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops cdvd release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include <time.h>
|
|
||||||
#include "resource.h"
|
|
||||||
#define _IN_CDR
|
|
||||||
#include "externals.h"
|
|
||||||
#define CDVDdefs
|
|
||||||
#include "PS2Etypes.h"
|
|
||||||
#include "PS2Edefs.h"
|
|
||||||
#include "libiso.h"
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
#define SMALLDEBUG 1
|
|
||||||
#include <dbgout.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// PCSX2 CDVD interface:
|
|
||||||
|
|
||||||
EXPORT_GCC char * CALLBACK PS2EgetLibName();
|
|
||||||
EXPORT_GCC unsigned long CALLBACK PS2EgetLibType();
|
|
||||||
EXPORT_GCC unsigned long CALLBACK PS2EgetLibVersion2(unsigned long type);
|
|
||||||
EXPORT_GCC long CALLBACK CDVDinit();
|
|
||||||
EXPORT_GCC void CALLBACK CDVDshutdown();
|
|
||||||
EXPORT_GCC long CALLBACK CDVDopen(const char* pTitle);
|
|
||||||
EXPORT_GCC void CALLBACK CDVDclose();
|
|
||||||
EXPORT_GCC long CALLBACK CDVDtest();
|
|
||||||
EXPORT_GCC long CALLBACK CDVDreadTrack(unsigned long lsn, int mode);
|
|
||||||
EXPORT_GCC unsigned char * CALLBACK CDVDgetBuffer();
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTN(cdvdTN *Buffer);
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTD(unsigned char track, cdvdTD *Buffer);
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetDiskType();
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTrayStatus();
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const unsigned char version = PS2E_CDVD_VERSION;
|
|
||||||
const unsigned char revision = 1;
|
|
||||||
const unsigned char build = 3;
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
char *libraryName = "P.E.Op.S. CDVD (Debug, CDDA mod)";
|
|
||||||
#else
|
|
||||||
char *libraryName = "P.E.Op.S. CDVD (CDDA mod)";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL bIsOpen=FALSE; // flag: open called once
|
|
||||||
BOOL bCDDAPlay=FALSE; // flag: audio is playing
|
|
||||||
int iCDROK=0; // !=0: cd is ok
|
|
||||||
int iCDType=CDVD_TYPE_UNKNOWN; // CD/DVD
|
|
||||||
int iCheckTrayStatus=0; // if 0 : report tray as closed, else try a real check
|
|
||||||
void *fdump;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// usual info funcs
|
|
||||||
|
|
||||||
EXPORT_GCC char * CALLBACK PS2EgetLibName()
|
|
||||||
{
|
|
||||||
return libraryName;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC unsigned long CALLBACK PS2EgetLibType()
|
|
||||||
{
|
|
||||||
return PS2E_LT_CDVD;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC unsigned long CALLBACK PS2EgetLibVersion2(unsigned long type)
|
|
||||||
{
|
|
||||||
return version<<16|revision<<8|build;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
EXPORT_GCC unsigned long CALLBACK PS2EgetCpuPlatform(void)
|
|
||||||
{
|
|
||||||
return PS2E_X86;
|
|
||||||
// return PS2E_X86_64;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
s32 msf_to_lba(u8 m, u8 s, u8 f) {
|
|
||||||
u32 lsn;
|
|
||||||
lsn = f;
|
|
||||||
lsn+=(s - 2) * 75;
|
|
||||||
lsn+= m * 75 * 60;
|
|
||||||
return lsn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lba_to_msf(s32 lba, u8* m, u8* s, u8* f) {
|
|
||||||
lba += 150;
|
|
||||||
*m = (u8)(lba / (60*75));
|
|
||||||
*s = (u8)((lba / 75) % 60);
|
|
||||||
*f = (u8)(lba % 75);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// init: called once at library load
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDinit()
|
|
||||||
{
|
|
||||||
szSUBF[0]=0; // just init the filename buffers
|
|
||||||
szPPF[0] =0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// shutdown: called once at final exit
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK CDVDshutdown()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// open: called, when games starts/cd has been changed
|
|
||||||
|
|
||||||
int CheckDiskType(int baseType);
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDopen(const char* pTitle)
|
|
||||||
{
|
|
||||||
int i,audioTracks,dataTracks;
|
|
||||||
cdvdTD T;
|
|
||||||
if(bIsOpen) // double-open check (if the main emu coder doesn't know what he is doing ;)
|
|
||||||
{
|
|
||||||
if(iCDROK<=0) return -1;
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bIsOpen=TRUE; // ok, open func called once
|
|
||||||
|
|
||||||
ReadConfig(); // read user config
|
|
||||||
|
|
||||||
BuildPPFCache(); // build ppf cache
|
|
||||||
|
|
||||||
BuildSUBCache(); // build sub cache
|
|
||||||
|
|
||||||
CreateREADBufs(); // setup generic read buffers
|
|
||||||
|
|
||||||
CreateGenEvent(); // create read event
|
|
||||||
|
|
||||||
iCDROK=OpenGenCD(iCD_AD,iCD_TA,iCD_LU); // generic open, setup read func
|
|
||||||
|
|
||||||
if(iCDROK<=0) {iCDROK=0;return -1;}
|
|
||||||
|
|
||||||
ReadTOC(); // read the toc
|
|
||||||
|
|
||||||
SetGenCDSpeed(0); // try to change the reading speed (if wanted)
|
|
||||||
|
|
||||||
iCDType=CDVD_TYPE_UNKNOWN; // let's look after the disc type
|
|
||||||
// (funny stuff taken from Xobro's/Florin's bin plugin)
|
|
||||||
if(CDVDreadTrack(16,CDVD_MODE_2048)==0)
|
|
||||||
{
|
|
||||||
struct cdVolDesc *volDesc;
|
|
||||||
volDesc=(struct cdVolDesc *)CDVDgetBuffer();
|
|
||||||
if(volDesc)
|
|
||||||
{
|
|
||||||
|
|
||||||
//todo: CDVD_TYPE_CDDA
|
|
||||||
|
|
||||||
if(volDesc->rootToc.tocSize==2048)
|
|
||||||
iCDType = CDVD_TYPE_DETCTCD;
|
|
||||||
else iCDType = CDVD_TYPE_DETCTDVDS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr," * CDVD Disk Open: %d tracks (%d to %d):\n",sTOC.cLastTrack-sTOC.cFirstTrack+1,sTOC.cFirstTrack,sTOC.cLastTrack);
|
|
||||||
|
|
||||||
audioTracks=dataTracks=0;
|
|
||||||
for(i=sTOC.cFirstTrack;i<=sTOC.cLastTrack;i++)
|
|
||||||
{
|
|
||||||
CDVDgetTD(i,&T);
|
|
||||||
if(T.type==CDVD_AUDIO_TRACK) {
|
|
||||||
audioTracks++;
|
|
||||||
fprintf(stderr," * * Track %d: Audio (%d sectors)\n",i,T.lsn);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dataTracks++;
|
|
||||||
fprintf(stderr," * * Track %d: Data (Mode %d) (%d sectors)\n",i,((T.type==CDVD_MODE1_TRACK)?1:2),T.lsn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((dataTracks==0)&&(audioTracks>0))
|
|
||||||
iCDType=CDVD_TYPE_CDDA;
|
|
||||||
else if(dataTracks>0)
|
|
||||||
iCDType=CheckDiskType(iCDType);
|
|
||||||
|
|
||||||
if((iCDType==CDVD_TYPE_ILLEGAL)&&(audioTracks>0))
|
|
||||||
iCDType=CDVD_TYPE_CDDA;
|
|
||||||
else if((iCDType==CDVD_TYPE_PS2CD)&&(audioTracks>0))
|
|
||||||
iCDType=CDVD_TYPE_PS2CDDA;
|
|
||||||
else if((iCDType==CDVD_TYPE_PSCD)&&(audioTracks>0))
|
|
||||||
iCDType=CDVD_TYPE_PSCDDA;
|
|
||||||
|
|
||||||
switch(iCDType) {
|
|
||||||
case CDVD_TYPE_ILLEGAL: // Illegal Disc
|
|
||||||
fprintf(stderr," * Disk Type: Illegal Disk.\n");break;
|
|
||||||
case CDVD_TYPE_DVDV: // DVD Video
|
|
||||||
fprintf(stderr," * Disk Type: DVD Video.\n");break;
|
|
||||||
case CDVD_TYPE_CDDA: // Audio CD
|
|
||||||
fprintf(stderr," * Disk Type: CDDA.\n");break;
|
|
||||||
case CDVD_TYPE_PS2DVD: // PS2 DVD
|
|
||||||
fprintf(stderr," * Disk Type: PS2 DVD.\n");break;
|
|
||||||
case CDVD_TYPE_PS2CDDA: // PS2 CD (with audio)
|
|
||||||
fprintf(stderr," * Disk Type: PS2 CD+Audio.\n");break;
|
|
||||||
case CDVD_TYPE_PS2CD: // PS2 CD
|
|
||||||
fprintf(stderr," * Disk Type: PS2 CD.\n");break;
|
|
||||||
case CDVD_TYPE_PSCDDA: // PS CD (with audio)
|
|
||||||
fprintf(stderr," * Disk Type: PS1 CD+Audio.\n");break;
|
|
||||||
case CDVD_TYPE_PSCD: // PS CD
|
|
||||||
fprintf(stderr," * Disk Type: PS1 CD.\n");break;
|
|
||||||
case CDVD_TYPE_UNKNOWN: // Unknown
|
|
||||||
fprintf(stderr," * Disk Type: Unknown.\n");break;
|
|
||||||
case CDVD_TYPE_NODISC: // No Disc
|
|
||||||
fprintf(stderr," * Disk Type: No Disc.\n");break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if (iBlockDump)*/ {
|
|
||||||
// fdump = isoCreate("block.dump", ISOFLAGS_BLOCKDUMP);
|
|
||||||
fdump = NULL;
|
|
||||||
if (fdump) {
|
|
||||||
cdvdTD buf;
|
|
||||||
CDVDgetTD(0, &buf);
|
|
||||||
isoSetFormat(fdump, 0, 2352, buf.lsn);
|
|
||||||
}
|
|
||||||
} /*else {
|
|
||||||
fdump = NULL;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
return 0; // ok, done
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// close: called when emulation stops
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK CDVDclose()
|
|
||||||
{
|
|
||||||
if(!bIsOpen) return; // no open? no close...
|
|
||||||
|
|
||||||
if (fdump != NULL) {
|
|
||||||
isoClose(fdump);
|
|
||||||
}
|
|
||||||
bIsOpen=FALSE; // no more open
|
|
||||||
|
|
||||||
LockGenCDAccess(); // make sure that no more reading is happening
|
|
||||||
|
|
||||||
if(iCDROK) // cd was ok?
|
|
||||||
{
|
|
||||||
if(bCDDAPlay) {DoCDDAPlay(0);bCDDAPlay=FALSE;} // -> cdda playing? stop it
|
|
||||||
SetGenCDSpeed(1); // -> repair speed
|
|
||||||
CloseGenCD(); // -> cd not used anymore
|
|
||||||
}
|
|
||||||
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
FreeREADBufs(); // free read bufs
|
|
||||||
FreeGenEvent(); // free event
|
|
||||||
FreePPFCache(); // free ppf cache
|
|
||||||
FreeSUBCache(); // free sub cache
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// test: ah, well, always fine
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDtest()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// readSubQ: read subq from disc (only cds have subq data)
|
|
||||||
EXPORT_GCC long CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq)
|
|
||||||
{
|
|
||||||
u8 min, sec, frm;
|
|
||||||
|
|
||||||
if(!bIsOpen) CDVDopen("DVD"); // usual checks
|
|
||||||
if(!iCDROK) return -1;
|
|
||||||
|
|
||||||
// fake it
|
|
||||||
subq->ctrl = 4;
|
|
||||||
subq->mode = 1;
|
|
||||||
subq->trackNum = itob(1);
|
|
||||||
subq->trackIndex= itob(1);
|
|
||||||
|
|
||||||
lba_to_msf(lsn, &min, &sec, &frm);
|
|
||||||
subq->trackM = itob(min);
|
|
||||||
subq->trackS = itob(sec);
|
|
||||||
subq->trackF = itob(frm);
|
|
||||||
|
|
||||||
subq->pad = 0;
|
|
||||||
|
|
||||||
lba_to_msf(lsn + (2*75), &min, &sec, &frm);
|
|
||||||
subq->discM = itob(min);
|
|
||||||
subq->discS = itob(sec);
|
|
||||||
subq->discF = itob(frm);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// gettoc: ps2 style TOC
|
|
||||||
static int layer1start = -1;
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTOC(void* toc)
|
|
||||||
{
|
|
||||||
u32 type;
|
|
||||||
u8* tocBuff = (u8*)toc;
|
|
||||||
|
|
||||||
if(!bIsOpen) CDVDopen("DVD"); // not open? funny emu...
|
|
||||||
|
|
||||||
if(!iCDROK) return -1; // cd not ok?
|
|
||||||
|
|
||||||
type = CDVDgetDiskType();
|
|
||||||
|
|
||||||
if( type == CDVD_TYPE_DVDV ||
|
|
||||||
type == CDVD_TYPE_PS2DVD)
|
|
||||||
{
|
|
||||||
u32 lastaddr;
|
|
||||||
|
|
||||||
// get dvd structure format
|
|
||||||
// scsi command 0x43
|
|
||||||
memset(tocBuff, 0, 2048);
|
|
||||||
|
|
||||||
lastaddr = GetLastTrack1Addr();
|
|
||||||
if(layer1start > 0 || (layer1start != -2 && lastaddr > 0x280000) ) {
|
|
||||||
int off = 0;
|
|
||||||
FRAMEBUF* f = (FRAMEBUF*)malloc(sizeof(FRAMEBUF));
|
|
||||||
|
|
||||||
f->dwBufLen = iUsedBlockSize;
|
|
||||||
f->dwFrameCnt = 1;
|
|
||||||
|
|
||||||
|
|
||||||
// dual sided
|
|
||||||
tocBuff[ 0] = 0x24;
|
|
||||||
tocBuff[ 1] = 0x02;
|
|
||||||
tocBuff[ 2] = 0xF2;
|
|
||||||
tocBuff[ 3] = 0x00;
|
|
||||||
tocBuff[ 4] = 0x41;
|
|
||||||
tocBuff[ 5] = 0x95;
|
|
||||||
|
|
||||||
tocBuff[14] = 0x60; // dual sided, ptp
|
|
||||||
|
|
||||||
tocBuff[16] = 0x00;
|
|
||||||
tocBuff[17] = 0x03;
|
|
||||||
tocBuff[18] = 0x00;
|
|
||||||
tocBuff[19] = 0x00;
|
|
||||||
|
|
||||||
if( layer1start == -1 ) {
|
|
||||||
// search for it
|
|
||||||
printf("PeopsCDVD: searching for layer1... ");
|
|
||||||
for(layer1start = (lastaddr/2-0x10)&~0xf; layer1start < 0x200010; layer1start += 16) {
|
|
||||||
f->dwFrame = layer1start;
|
|
||||||
if( pReadFunc(TRUE,f) != SS_COMP ) {
|
|
||||||
layer1start = 0x200010;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// CD001
|
|
||||||
if( f->BufData[off+1] == 0x43 && f->BufData[off+2] == 0x44 && f->BufData[off+3] == 0x30 && f->BufData[off+4] == 0x30 && f->BufData[off+5] == 0x31 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( layer1start >= 0x200010 ) {
|
|
||||||
printf("Couldn't find second layer on dual layer... ignoring\n");
|
|
||||||
// fake it
|
|
||||||
tocBuff[ 0] = 0x04;
|
|
||||||
tocBuff[ 1] = 0x02;
|
|
||||||
tocBuff[ 2] = 0xF2;
|
|
||||||
tocBuff[ 3] = 0x00;
|
|
||||||
tocBuff[ 4] = 0x86;
|
|
||||||
tocBuff[ 5] = 0x72;
|
|
||||||
|
|
||||||
tocBuff[16] = 0x00;
|
|
||||||
tocBuff[17] = 0x03;
|
|
||||||
tocBuff[18] = 0x00;
|
|
||||||
tocBuff[19] = 0x00;
|
|
||||||
layer1start = -2;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("found at 0x%8.8x\n", layer1start);
|
|
||||||
layer1start = layer1start+0x30000-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tocBuff[20] = layer1start>>24;
|
|
||||||
tocBuff[21] = (layer1start>>16)&0xff;
|
|
||||||
tocBuff[22] = (layer1start>>8)&0xff;
|
|
||||||
tocBuff[23] = (layer1start>>0)&0xff;
|
|
||||||
|
|
||||||
free(f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// fake it
|
|
||||||
tocBuff[ 0] = 0x04;
|
|
||||||
tocBuff[ 1] = 0x02;
|
|
||||||
tocBuff[ 2] = 0xF2;
|
|
||||||
tocBuff[ 3] = 0x00;
|
|
||||||
tocBuff[ 4] = 0x86;
|
|
||||||
tocBuff[ 5] = 0x72;
|
|
||||||
|
|
||||||
tocBuff[16] = 0x00;
|
|
||||||
tocBuff[17] = 0x03;
|
|
||||||
tocBuff[18] = 0x00;
|
|
||||||
tocBuff[19] = 0x00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(type == CDVD_TYPE_CDDA ||
|
|
||||||
type == CDVD_TYPE_PS2CDDA ||
|
|
||||||
type == CDVD_TYPE_PS2CD ||
|
|
||||||
type == CDVD_TYPE_PSCDDA ||
|
|
||||||
type == CDVD_TYPE_PSCD)
|
|
||||||
{
|
|
||||||
// cd toc
|
|
||||||
// (could be replaced by 1 command that reads the full toc)
|
|
||||||
u8 min, sec, frm,i;
|
|
||||||
s32 err;
|
|
||||||
cdvdTN diskInfo;
|
|
||||||
cdvdTD trackInfo;
|
|
||||||
memset(tocBuff, 0, 1024);
|
|
||||||
if (CDVDgetTN(&diskInfo) == -1) { diskInfo.etrack = 0;diskInfo.strack = 1; }
|
|
||||||
if (CDVDgetTD(0, &trackInfo) == -1) trackInfo.lsn = 0;
|
|
||||||
|
|
||||||
tocBuff[0] = 0x41;
|
|
||||||
tocBuff[1] = 0x00;
|
|
||||||
|
|
||||||
//Number of FirstTrack
|
|
||||||
tocBuff[2] = 0xA0;
|
|
||||||
tocBuff[7] = itob(diskInfo.strack);
|
|
||||||
|
|
||||||
//Number of LastTrack
|
|
||||||
tocBuff[12] = 0xA1;
|
|
||||||
tocBuff[17] = itob(diskInfo.etrack);
|
|
||||||
|
|
||||||
//DiskLength
|
|
||||||
lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
|
|
||||||
tocBuff[22] = 0xA2;
|
|
||||||
tocBuff[27] = itob(min);
|
|
||||||
tocBuff[28] = itob(sec);
|
|
||||||
tocBuff[29] = itob(frm);
|
|
||||||
|
|
||||||
fprintf(stderr,"Track 0: %d mins %d secs %d frames\n",min,sec,frm);
|
|
||||||
|
|
||||||
for (i=diskInfo.strack; i<=diskInfo.etrack; i++)
|
|
||||||
{
|
|
||||||
err = CDVDgetTD(i, &trackInfo);
|
|
||||||
lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
|
|
||||||
tocBuff[i*10+30] = trackInfo.type;
|
|
||||||
tocBuff[i*10+32] = err == -1 ? 0 : itob(i); //number
|
|
||||||
tocBuff[i*10+37] = itob(min);
|
|
||||||
tocBuff[i*10+38] = itob(sec);
|
|
||||||
tocBuff[i*10+39] = itob(frm);
|
|
||||||
fprintf(stderr,"Track %d: %d mins %d secs %d frames\n",i,min,sec,frm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// gettn: first/last track num
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTN(cdvdTN *Buffer)
|
|
||||||
{
|
|
||||||
if(!bIsOpen) CDVDopen("DVD"); // not open? funny emu...
|
|
||||||
|
|
||||||
if(!iCDROK) // cd not ok?
|
|
||||||
{
|
|
||||||
Buffer->strack=1;
|
|
||||||
Buffer->etrack=1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadTOC(); // read the TOC
|
|
||||||
|
|
||||||
Buffer->strack=sTOC.cFirstTrack; // get the infos
|
|
||||||
Buffer->etrack=sTOC.cLastTrack;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// gettd: track addr
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTD(unsigned char track, cdvdTD *Buffer)
|
|
||||||
{
|
|
||||||
unsigned long lu,i;
|
|
||||||
unsigned char buffer[2352];
|
|
||||||
unsigned char *buf;
|
|
||||||
u8 t1;
|
|
||||||
|
|
||||||
if(!bIsOpen) CDVDopen("DVD"); // not open? funny emu...
|
|
||||||
|
|
||||||
if(!iCDROK) return -1; // cd not ok? bye
|
|
||||||
|
|
||||||
ReadTOC(); // read toc
|
|
||||||
|
|
||||||
/*
|
|
||||||
// PSEmu style:
|
|
||||||
if(track==0) // 0 = last track
|
|
||||||
{
|
|
||||||
lu=reOrder(sTOC.tracks[sTOC.cLastTrack].lAddr);
|
|
||||||
addr2time(lu,buffer);
|
|
||||||
}
|
|
||||||
else // others: track n
|
|
||||||
{
|
|
||||||
lu=reOrder(sTOC.tracks[track-1].lAddr);
|
|
||||||
addr2time(lu,buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer->minute = buffer[1];
|
|
||||||
Buffer->second = buffer[2];
|
|
||||||
Buffer->frame = buffer[3];
|
|
||||||
Buffer->type = iCDType;
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("Read Toc %d: %u\n",track,lu);
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
lu=0;
|
|
||||||
if(track==0)
|
|
||||||
lu=reOrder(sTOC.tracks[sTOC.cLastTrack].lAddr);
|
|
||||||
else
|
|
||||||
lu=reOrder(sTOC.tracks[track].lAddr);
|
|
||||||
//addr2time(lu,buffer);
|
|
||||||
|
|
||||||
Buffer->lsn=lu;
|
|
||||||
|
|
||||||
if(track==0)
|
|
||||||
Buffer->type = iCDType;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lu=0;
|
|
||||||
for(i=sTOC.cFirstTrack;i<track;i++)
|
|
||||||
lu+=sTOC.tracks[i].lAddr;
|
|
||||||
|
|
||||||
CDVDreadTrack(lu+16,CDVD_MODE_2352);
|
|
||||||
buf=CDVDgetBuffer();
|
|
||||||
|
|
||||||
if(buf!=NULL) memcpy(buffer,buf,2352);
|
|
||||||
else memset(buffer,0,2352);
|
|
||||||
|
|
||||||
if( (buffer[16]==01)
|
|
||||||
&&(buffer[17]=='C')
|
|
||||||
&&(buffer[18]=='D')
|
|
||||||
)
|
|
||||||
t1 = CDVD_MODE1_TRACK;
|
|
||||||
else if( (buffer[24]==01)
|
|
||||||
&&(buffer[25]=='C')
|
|
||||||
&&(buffer[26]=='D')
|
|
||||||
)
|
|
||||||
t1 = CDVD_MODE2_TRACK;
|
|
||||||
else t1 = CDVD_AUDIO_TRACK;
|
|
||||||
|
|
||||||
Buffer->type=t1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// readtrack: start reading at given address
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDreadTrack(unsigned long lsn, int mode)
|
|
||||||
{
|
|
||||||
if(!bIsOpen) CDVDopen("DVD"); // usual checks
|
|
||||||
if(!iCDROK) return -1;
|
|
||||||
if(bCDDAPlay) bCDDAPlay=FALSE;
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("Read Track %u: %d\n",lsn,mode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lLastAccessedAddr=lsn; // store read track values (for getbuffer)
|
|
||||||
iLastAccessedMode=mode;
|
|
||||||
|
|
||||||
if(!pReadTrackFunc(lLastAccessedAddr)) // start reading
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// getbuffer: will be called after readtrack, to get ptr
|
|
||||||
// to data
|
|
||||||
|
|
||||||
// small helper buffer to get bigger block sizes
|
|
||||||
unsigned char cDataAndSub[2368];
|
|
||||||
|
|
||||||
EXPORT_GCC unsigned char * CALLBACK CDVDgetBuffer()
|
|
||||||
{
|
|
||||||
unsigned char * pbuffer;
|
|
||||||
|
|
||||||
if(!bIsOpen) CDVDopen("DVD");
|
|
||||||
|
|
||||||
if(pGetPtrFunc) pGetPtrFunc(); // get ptr on thread modes
|
|
||||||
|
|
||||||
pbuffer=pCurrReadBuf; // init buffer pointer
|
|
||||||
if (fdump != NULL) {
|
|
||||||
isoWriteBlock(fdump, pbuffer, lLastAccessedAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(iLastAccessedMode!=iUsedMode)
|
|
||||||
{
|
|
||||||
switch(iLastAccessedMode) // what does the emu want?
|
|
||||||
{//------------------------------------------------//
|
|
||||||
case CDVD_MODE_2048:
|
|
||||||
{
|
|
||||||
if(iUsedBlockSize==2352) pbuffer+=24;
|
|
||||||
}break;
|
|
||||||
//------------------------------------------------//
|
|
||||||
case CDVD_MODE_2352:
|
|
||||||
{
|
|
||||||
if(iUsedBlockSize==2048)
|
|
||||||
{
|
|
||||||
memset(cDataAndSub,0,2368);
|
|
||||||
memcpy(cDataAndSub+24,pbuffer,2048);
|
|
||||||
pbuffer=cDataAndSub;
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
//------------------------------------------------//
|
|
||||||
case CDVD_MODE_2340:
|
|
||||||
{
|
|
||||||
if(iUsedBlockSize==2048)
|
|
||||||
{
|
|
||||||
memset(cDataAndSub,0,2368);
|
|
||||||
memcpy(cDataAndSub+12,pbuffer,2048);
|
|
||||||
pbuffer=cDataAndSub;
|
|
||||||
}
|
|
||||||
else pbuffer+=12;
|
|
||||||
}break;
|
|
||||||
//------------------------------------------------//
|
|
||||||
case CDVD_MODE_2328:
|
|
||||||
{
|
|
||||||
if(iUsedBlockSize==2048)
|
|
||||||
{
|
|
||||||
memset(cDataAndSub,0,2368);
|
|
||||||
memcpy(cDataAndSub+0,pbuffer,2048);
|
|
||||||
pbuffer=cDataAndSub;
|
|
||||||
}
|
|
||||||
else pbuffer+=24;
|
|
||||||
}break;
|
|
||||||
//------------------------------------------------//
|
|
||||||
case CDVD_MODE_2368:
|
|
||||||
{
|
|
||||||
if(iUsedBlockSize==2048)
|
|
||||||
{
|
|
||||||
memset(cDataAndSub,0,2368);
|
|
||||||
memcpy(cDataAndSub+24,pbuffer,2048);
|
|
||||||
pbuffer=cDataAndSub;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// NO SUBCHANNEL SUPPORT RIGHT NOW!!!
|
|
||||||
{
|
|
||||||
if(subHead) // some sub file?
|
|
||||||
CheckSUBCache(lLastAccessedAddr); // -> get cached subs
|
|
||||||
else
|
|
||||||
if(iUseSubReading!=1 && pCurrSubBuf) // no direct cd sub read?
|
|
||||||
FakeSubData(lLastAccessedAddr); // -> fake the data
|
|
||||||
memcpy(cDataAndSub,pCurrReadBuf,2352);
|
|
||||||
if(pCurrSubBuf)
|
|
||||||
memcpy(cDataAndSub+2352,pCurrSubBuf+12,16);
|
|
||||||
pbuffer=cDataAndSub;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
//------------------------------------------------//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("get buf %d\n",iLastAccessedMode);
|
|
||||||
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
int k;
|
|
||||||
for(k=0;k<2352;k++)
|
|
||||||
auxprintf("%02x ",*(pbuffer+k));
|
|
||||||
auxprintf("\n\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return pbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetDiskType()
|
|
||||||
{
|
|
||||||
return iCDType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// CDVDgetTrayStatus
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDVDgetTrayStatus()
|
|
||||||
{
|
|
||||||
static time_t to=0;
|
|
||||||
static long lLastTrayState=CDVD_TRAY_CLOSE;
|
|
||||||
|
|
||||||
if(to==time(NULL)) return lLastTrayState; // we only check once per second
|
|
||||||
to = time(NULL);
|
|
||||||
|
|
||||||
lLastTrayState=CDVD_TRAY_CLOSE; // init state with "closed"
|
|
||||||
|
|
||||||
if(iCheckTrayStatus) // user really want a tray check
|
|
||||||
{
|
|
||||||
int iStatus;
|
|
||||||
|
|
||||||
LockGenCDAccess(); // make sure that no more reading is happening
|
|
||||||
iStatus=GetSCSIStatus(iCD_AD,iCD_TA,iCD_LU); // get device status
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
if(iStatus==SS_ERR)
|
|
||||||
lLastTrayState=CDVD_TRAY_OPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("check %d -> %d\n",to,lLastTrayState);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return lLastTrayState;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC s32 CALLBACK CDVDctrlTrayOpen() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC s32 CALLBACK CDVDctrlTrayClose() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// configure: shows config window
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK CDVDconfigure()
|
|
||||||
{
|
|
||||||
if(iCDROK) // mmm... someone has already called Open? bad
|
|
||||||
{MessageBeep((UINT)-1);return;}
|
|
||||||
|
|
||||||
CreateGenEvent(); // we need an event handle
|
|
||||||
|
|
||||||
DialogBox(hInst,MAKEINTRESOURCE(IDD_CONFIG), // call dialog
|
|
||||||
GetActiveWindow(),(DLGPROC)CDRDlgProc);
|
|
||||||
|
|
||||||
FreeGenEvent(); // free event handle
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// about: shows about window
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK CDVDabout()
|
|
||||||
{
|
|
||||||
DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUT),
|
|
||||||
GetActiveWindow(),(DLGPROC)AboutDlgProc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/*
|
|
||||||
// CURRENTLY UNUSED OLD STUFF FROM PSX CD PLUGIN:
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// audioplay: PLAYSECTOR is NOT BCD coded !!!
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDRplay(unsigned char * sector)
|
|
||||||
{
|
|
||||||
if(!bIsOpen) CDVDopen();
|
|
||||||
if(!iCDROK) return PSE_ERR_FATAL;
|
|
||||||
|
|
||||||
if(!DoCDDAPlay(time2addr(sector))) // start playing
|
|
||||||
return PSE_CDR_ERR_NOREAD;
|
|
||||||
|
|
||||||
bCDDAPlay=TRUE; // raise flag: we are playing
|
|
||||||
|
|
||||||
return PSE_CDR_ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// audiostop: stops cdda playing
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDRstop(void)
|
|
||||||
{
|
|
||||||
if(!bCDDAPlay) return PSE_ERR_FATAL;
|
|
||||||
|
|
||||||
DoCDDAPlay(0); // stop cdda
|
|
||||||
|
|
||||||
bCDDAPlay=FALSE; // reset flag: no more playing
|
|
||||||
|
|
||||||
return PSE_CDR_ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// getdriveletter
|
|
||||||
|
|
||||||
EXPORT_GCC char CALLBACK CDRgetDriveLetter(void)
|
|
||||||
{
|
|
||||||
if(!iCDROK) return 0; // not open? no way to get the letter
|
|
||||||
|
|
||||||
if(iInterfaceMode==2 || iInterfaceMode==3) // w2k/xp: easy
|
|
||||||
{
|
|
||||||
return MapIOCTLDriveLetter(iCD_AD,iCD_TA,iCD_LU);
|
|
||||||
}
|
|
||||||
else // but with aspi???
|
|
||||||
{ // -> no idea yet (maybe registry read...pfff)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// getstatus: pcsx func... poorly supported here
|
|
||||||
// problem is: func will be called often, which
|
|
||||||
// would block all of my cdr reading if I would use
|
|
||||||
// lotsa scsi commands
|
|
||||||
|
|
||||||
struct CdrStat
|
|
||||||
{
|
|
||||||
unsigned long Type;
|
|
||||||
unsigned long Status;
|
|
||||||
unsigned char Time[3]; // current playing time
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CdrStat ostat;
|
|
||||||
|
|
||||||
// reads cdr status
|
|
||||||
// type:
|
|
||||||
// 0x00 - unknown
|
|
||||||
// 0x01 - data
|
|
||||||
// 0x02 - audio
|
|
||||||
// 0xff - no cdrom
|
|
||||||
// status:
|
|
||||||
// 0x00 - unknown
|
|
||||||
// 0x02 - error
|
|
||||||
// 0x08 - seek error
|
|
||||||
// 0x10 - shell open
|
|
||||||
// 0x20 - reading
|
|
||||||
// 0x40 - seeking
|
|
||||||
// 0x80 - playing
|
|
||||||
// time:
|
|
||||||
// byte 0 - minute
|
|
||||||
// byte 1 - second
|
|
||||||
// byte 2 - frame
|
|
||||||
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK CDRgetStatus(struct CdrStat *stat)
|
|
||||||
{
|
|
||||||
int iStatus;
|
|
||||||
static time_t to;
|
|
||||||
|
|
||||||
if(!bCDDAPlay) // if not playing update stat only once in a second
|
|
||||||
{
|
|
||||||
if(to<time(NULL))
|
|
||||||
{
|
|
||||||
to = time(NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(stat, &ostat, sizeof(struct CdrStat));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(stat, 0, sizeof(struct CdrStat));
|
|
||||||
|
|
||||||
if(!iCDROK) return -1; // not opened? bye
|
|
||||||
|
|
||||||
if(bCDDAPlay) // cdda is playing?
|
|
||||||
{
|
|
||||||
unsigned char * pB=GetCDDAPlayPosition(); // -> get pos
|
|
||||||
stat->Type = 0x02; // -> audio
|
|
||||||
if(pB)
|
|
||||||
{
|
|
||||||
stat->Status|=0x80; // --> playing flag
|
|
||||||
stat->Time[0]=pB[18]; // --> and curr play time
|
|
||||||
stat->Time[1]=pB[19];
|
|
||||||
stat->Time[2]=pB[20];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // cdda not playing?
|
|
||||||
{
|
|
||||||
stat->Type = 0x01; // -> data
|
|
||||||
}
|
|
||||||
|
|
||||||
LockGenCDAccess(); // make sure that no more reading is happening
|
|
||||||
iStatus=GetSCSIStatus(iCD_AD,iCD_TA,iCD_LU); // get device status
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
if(iStatus==SS_ERR)
|
|
||||||
{ // no cdrom?
|
|
||||||
stat->Type = 0xff;
|
|
||||||
stat->Status|= 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&ostat, stat, sizeof(struct CdrStat));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
|
@ -1,527 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cfg.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "resource.h"
|
|
||||||
#define _IN_CFG
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// read config from registry
|
|
||||||
|
|
||||||
void ReadConfig(void)
|
|
||||||
{
|
|
||||||
HKEY myKey;DWORD temp,type,size;
|
|
||||||
|
|
||||||
// init values
|
|
||||||
|
|
||||||
iCD_AD=-1;
|
|
||||||
iCD_TA=-1;
|
|
||||||
iCD_LU=-1;
|
|
||||||
iRType=0;
|
|
||||||
iUseSpeedLimit=0;
|
|
||||||
iSpeedLimit=2;
|
|
||||||
iNoWait=0;
|
|
||||||
iMaxRetry=5;
|
|
||||||
iShowReadErr=0;
|
|
||||||
iUsePPF=0;
|
|
||||||
iUseSubReading=0;
|
|
||||||
iUseDataCache=0;
|
|
||||||
iCheckTrayStatus=0;
|
|
||||||
memset(szPPF,0,260);
|
|
||||||
memset(szSUBF,0,260);
|
|
||||||
|
|
||||||
// read values
|
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\PS2Eplugin\\CDVD\\CDVDPeops",0,KEY_ALL_ACCESS,&myKey)==ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"Adapter",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iCD_AD=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"Target",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iCD_TA=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"LUN",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iCD_LU=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseCaching",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseCaching=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseDataCache",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseDataCache=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseSpeedLimit",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseSpeedLimit=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"SpeedLimit",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iSpeedLimit=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"NoWait",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iNoWait=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"CheckTrayStatus",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iCheckTrayStatus=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"MaxRetry",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iMaxRetry=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"ShowReadErr",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iShowReadErr=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UsePPF",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUsePPF=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseSubReading",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseSubReading=(int)temp;
|
|
||||||
size=259;
|
|
||||||
RegQueryValueEx(myKey,"PPFFile",0,&type,(LPBYTE)szPPF,&size);
|
|
||||||
size=259;
|
|
||||||
RegQueryValueEx(myKey,"SCFile",0,&type,(LPBYTE)szSUBF,&size);
|
|
||||||
|
|
||||||
RegCloseKey(myKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// disabled for now
|
|
||||||
iUsePPF=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// write user config
|
|
||||||
|
|
||||||
void WriteConfig(void)
|
|
||||||
{
|
|
||||||
HKEY myKey;DWORD myDisp,temp;
|
|
||||||
|
|
||||||
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\PS2Eplugin\\CDVD\\CDVDPeops",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&myKey,&myDisp);
|
|
||||||
temp=iInterfaceMode;
|
|
||||||
RegSetValueEx(myKey,"InterfaceMode",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iCD_AD;
|
|
||||||
RegSetValueEx(myKey,"Adapter",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iCD_TA;
|
|
||||||
RegSetValueEx(myKey,"Target",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iCD_LU;
|
|
||||||
RegSetValueEx(myKey,"LUN",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseCaching;
|
|
||||||
RegSetValueEx(myKey,"UseCaching",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseDataCache;
|
|
||||||
RegSetValueEx(myKey,"UseDataCache",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseSpeedLimit;
|
|
||||||
RegSetValueEx(myKey,"UseSpeedLimit",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iSpeedLimit;
|
|
||||||
RegSetValueEx(myKey,"SpeedLimit",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iNoWait;
|
|
||||||
RegSetValueEx(myKey,"NoWait",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iCheckTrayStatus ;
|
|
||||||
RegSetValueEx(myKey,"CheckTrayStatus",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iMaxRetry;
|
|
||||||
RegSetValueEx(myKey,"MaxRetry",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iShowReadErr;
|
|
||||||
RegSetValueEx(myKey,"ShowReadErr",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUsePPF;
|
|
||||||
RegSetValueEx(myKey,"UsePPF",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseSubReading;
|
|
||||||
RegSetValueEx(myKey,"UseSubReading",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
|
|
||||||
RegSetValueEx(myKey,"PPFFile",0,REG_BINARY,(LPBYTE)szPPF,259);
|
|
||||||
RegSetValueEx(myKey,"SCFile",0,REG_BINARY,(LPBYTE)szSUBF,259);
|
|
||||||
|
|
||||||
RegCloseKey(myKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// choose ppf/sbi/m3s file name
|
|
||||||
|
|
||||||
void OnChooseFile(HWND hW,int iFType)
|
|
||||||
{
|
|
||||||
OPENFILENAME ofn;char szB[260];BOOL b;
|
|
||||||
|
|
||||||
ofn.lStructSize=sizeof(OPENFILENAME);
|
|
||||||
ofn.hwndOwner=hW;
|
|
||||||
ofn.hInstance=NULL;
|
|
||||||
if(iFType==0) ofn.lpstrFilter="PPF Files\0*.PPF\0\0\0";
|
|
||||||
else if(iFType==1) ofn.lpstrFilter="SBI Files\0*.SBI\0M3S Files\0*.M3S\0\0\0";
|
|
||||||
else if(iFType==2) ofn.lpstrFilter="SUB Files\0*.SUB\0\0\0";
|
|
||||||
else if(iFType==3) ofn.lpstrFilter="SBI Files\0*.SBI\0\0\0";
|
|
||||||
else ofn.lpstrFilter="M3S Files\0*.M3S\0\0\0";
|
|
||||||
|
|
||||||
ofn.lpstrCustomFilter=NULL;
|
|
||||||
ofn.nMaxCustFilter=0;
|
|
||||||
ofn.nFilterIndex=0;
|
|
||||||
if(iFType==0) GetDlgItemText(hW,IDC_PPFFILE,szB,259);
|
|
||||||
else if(iFType==1) GetDlgItemText(hW,IDC_SUBFILE,szB,259);
|
|
||||||
else if(iFType==2) GetDlgItemText(hW,IDC_SUBFILEEDIT,szB,259);
|
|
||||||
else if(iFType==3) GetDlgItemText(hW,IDC_OUTFILEEDIT,szB,259);
|
|
||||||
else GetDlgItemText(hW,IDC_OUTFILEEDIT,szB,259);
|
|
||||||
|
|
||||||
ofn.lpstrFile=szB;
|
|
||||||
ofn.nMaxFile=259;
|
|
||||||
ofn.lpstrFileTitle=NULL;
|
|
||||||
ofn.nMaxFileTitle=0;
|
|
||||||
ofn.lpstrInitialDir=NULL;
|
|
||||||
ofn.lpstrTitle=NULL;
|
|
||||||
if(iFType<3)
|
|
||||||
ofn.Flags=OFN_FILEMUSTEXIST|OFN_NOCHANGEDIR|OFN_HIDEREADONLY;
|
|
||||||
else
|
|
||||||
ofn.Flags=OFN_CREATEPROMPT|OFN_NOCHANGEDIR|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
|
|
||||||
ofn.nFileOffset=0;
|
|
||||||
ofn.nFileExtension=0;
|
|
||||||
ofn.lpstrDefExt=0;
|
|
||||||
ofn.lCustData=0;
|
|
||||||
ofn.lpfnHook=NULL;
|
|
||||||
ofn.lpTemplateName=NULL;
|
|
||||||
|
|
||||||
if(iFType<3)
|
|
||||||
b=GetOpenFileName(&ofn);
|
|
||||||
else b=GetSaveFileName(&ofn);
|
|
||||||
|
|
||||||
if(b)
|
|
||||||
{
|
|
||||||
if(iFType==0) SetDlgItemText(hW,IDC_PPFFILE,szB);
|
|
||||||
else if(iFType==1) SetDlgItemText(hW,IDC_SUBFILE,szB);
|
|
||||||
else if(iFType==2) SetDlgItemText(hW,IDC_SUBFILEEDIT,szB);
|
|
||||||
else if(iFType==3) SetDlgItemText(hW,IDC_OUTFILEEDIT,szB);
|
|
||||||
else SetDlgItemText(hW,IDC_OUTFILEEDIT,szB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// file drive combo
|
|
||||||
|
|
||||||
void EnumDrives(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC;char szB[256];int i=0,k=0,iNum;
|
|
||||||
char * p, * pBuf, * pN;
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_DRIVE);
|
|
||||||
ComboBox_ResetContent(hWC);
|
|
||||||
ComboBox_AddString(hWC,"NONE"); // add always existing 'none'
|
|
||||||
|
|
||||||
wsprintf(szB,"[%d:%d:%d",iCD_AD,iCD_TA,iCD_LU); // make current user info text
|
|
||||||
|
|
||||||
pN=pBuf=(char *)malloc(32768);
|
|
||||||
memset(pBuf,0,32768);
|
|
||||||
iNum=GetGenCDDrives(pBuf); // get the system cd drives list
|
|
||||||
|
|
||||||
for(i=0;i<iNum;i++) // loop drives
|
|
||||||
{
|
|
||||||
ComboBox_AddString(hWC,pN); // -> add drive name
|
|
||||||
p=strchr(pN,']');
|
|
||||||
if(p)
|
|
||||||
{
|
|
||||||
*p=0;
|
|
||||||
if(strcmp(szB,pN)==0) k=i+1; // -> is it the current user drive? sel it
|
|
||||||
*p=']';
|
|
||||||
}
|
|
||||||
pN+=strlen(pN)+1; // next drive in buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pBuf);
|
|
||||||
|
|
||||||
ComboBox_SetCurSel(hWC,k); // do the drive sel
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// get curr selected drive
|
|
||||||
|
|
||||||
void GetCDRInfos(HWND hW,int * iA, int * iT,int * iL)
|
|
||||||
{
|
|
||||||
HWND hWC=GetDlgItem(hW,IDC_DRIVE);
|
|
||||||
char szB[256];int i;char * p;
|
|
||||||
|
|
||||||
i=ComboBox_GetCurSel(hWC);
|
|
||||||
if(i<=0) // none selected
|
|
||||||
{
|
|
||||||
*iA=-1;*iT=-1;*iL=-1;
|
|
||||||
MessageBox(hW,"Please select a cdrom drive!","Config error",MB_OK|MB_ICONINFORMATION);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComboBox_GetLBText(hWC,i,szB); // get cd text
|
|
||||||
p=szB+1;
|
|
||||||
*iA=atoi(p); // get AD,TA,LU
|
|
||||||
p=strchr(szB,':')+1;
|
|
||||||
*iT=atoi(p);
|
|
||||||
p=strchr(p,':')+1;
|
|
||||||
*iL=atoi(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// interface mode has changed
|
|
||||||
|
|
||||||
void OnIMode(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC=GetDlgItem(hW,IDC_IMODE);
|
|
||||||
int iM = ComboBox_GetCurSel(hWC);
|
|
||||||
|
|
||||||
GetCDRInfos(hW,&iCD_AD,&iCD_TA,&iCD_LU); // get sel drive
|
|
||||||
CloseGenInterface(); // close current interface
|
|
||||||
iInterfaceMode=iM; // set new interface mode
|
|
||||||
OpenGenInterface(); // open new interface
|
|
||||||
ComboBox_SetCurSel(hWC,iInterfaceMode); // sel interface again (maybe it was not supported on open)
|
|
||||||
EnumDrives(hW); // enum drives again
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// cache mode has changed
|
|
||||||
|
|
||||||
void OnCache(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC=GetDlgItem(hW,IDC_CACHE);
|
|
||||||
if(ComboBox_GetCurSel(hWC)<=0)
|
|
||||||
ShowWindow(GetDlgItem(hW,IDC_DATACACHE),SW_HIDE);
|
|
||||||
else ShowWindow(GetDlgItem(hW,IDC_DATACACHE),SW_SHOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// show/hide files depending on subc mode
|
|
||||||
|
|
||||||
void ShowSubFileStuff(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC=GetDlgItem(hW,IDC_SUBCHAN0);
|
|
||||||
int iShow,iSel=ComboBox_GetCurSel(hWC);
|
|
||||||
|
|
||||||
if(iSel==2) iShow=SW_SHOW;
|
|
||||||
else iShow=SW_HIDE;
|
|
||||||
|
|
||||||
ShowWindow(GetDlgItem(hW,IDC_SFSTATIC),iShow);
|
|
||||||
ShowWindow(GetDlgItem(hW,IDC_SUBFILE),iShow);
|
|
||||||
ShowWindow(GetDlgItem(hW,IDC_CHOOSESUBF),iShow);
|
|
||||||
|
|
||||||
if(iSel==1)
|
|
||||||
{
|
|
||||||
ComboBox_SetCurSel(GetDlgItem(hW,IDC_CACHE),0);
|
|
||||||
ShowWindow(GetDlgItem(hW,IDC_DATACACHE),SW_HIDE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// init dialog
|
|
||||||
|
|
||||||
BOOL OnInitCDRDialog(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC;int i=0;
|
|
||||||
|
|
||||||
ReadConfig(); // read config
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_IMODE); // interface
|
|
||||||
ComboBox_AddString(hWC,"NONE");
|
|
||||||
ComboBox_AddString(hWC,"W9X/ME - ASPI scsi commands");
|
|
||||||
ComboBox_AddString(hWC,"W2K/XP - IOCTL scsi commands");
|
|
||||||
|
|
||||||
// not supported with my dvd drive - DISABLED!
|
|
||||||
// ComboBox_AddString(hWC,"W2K/XP - IOCTL raw reading");
|
|
||||||
|
|
||||||
ComboBox_SetCurSel(hWC,iInterfaceMode);
|
|
||||||
|
|
||||||
EnumDrives(hW); // enum drives
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_CACHE); // caching
|
|
||||||
ComboBox_AddString(hWC,"None - reads one sector");
|
|
||||||
ComboBox_AddString(hWC,"Read ahead - fast, reads more sectors at once");
|
|
||||||
ComboBox_AddString(hWC,"Async read - faster, additional asynchronous reads");
|
|
||||||
ComboBox_AddString(hWC,"Thread read - fast with IOCTL, always async reads");
|
|
||||||
ComboBox_AddString(hWC,"Smooth read - for drives with PS2 CD/DVD reading troubles");
|
|
||||||
ComboBox_SetCurSel(hWC,iUseCaching);
|
|
||||||
|
|
||||||
if(iUseDataCache)
|
|
||||||
CheckDlgButton(hW,IDC_DATACACHE,TRUE);
|
|
||||||
if(!iUseCaching)
|
|
||||||
ShowWindow(GetDlgItem(hW,IDC_DATACACHE),SW_HIDE);
|
|
||||||
|
|
||||||
if(iUseSpeedLimit) // speed limit
|
|
||||||
CheckDlgButton(hW,IDC_SPEEDLIMIT,TRUE);
|
|
||||||
|
|
||||||
if(iNoWait) // wait for drive
|
|
||||||
CheckDlgButton(hW,IDC_NOWAIT,TRUE);
|
|
||||||
|
|
||||||
if(iCheckTrayStatus) // tray status
|
|
||||||
CheckDlgButton(hW,IDC_TRAYSTATE,TRUE);
|
|
||||||
|
|
||||||
SetDlgItemInt(hW,IDC_RETRY,iMaxRetry,FALSE); // retry on error
|
|
||||||
if(iMaxRetry) CheckDlgButton(hW,IDC_TRYAGAIN,TRUE);
|
|
||||||
if(iShowReadErr) CheckDlgButton(hW,IDC_SHOWREADERR,TRUE);
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_SUBCHAN0); // subchannel mode
|
|
||||||
ComboBox_AddString(hWC,"Don't read subchannels");
|
|
||||||
ComboBox_AddString(hWC,"Read subchannels (slow, few drives support it, best chances with BE mode)");
|
|
||||||
ComboBox_AddString(hWC,"Use subchannel SBI/M3S info file (recommended)");
|
|
||||||
ComboBox_SetCurSel(hWC,iUseSubReading);
|
|
||||||
|
|
||||||
ShowSubFileStuff(hW); // show/hide subc controls
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_SPEED); // speed limit
|
|
||||||
ComboBox_AddString(hWC,"2 X");
|
|
||||||
ComboBox_AddString(hWC,"4 X");
|
|
||||||
ComboBox_AddString(hWC,"8 X");
|
|
||||||
ComboBox_AddString(hWC,"16 X");
|
|
||||||
|
|
||||||
i=0;
|
|
||||||
if(iSpeedLimit==4) i=1;
|
|
||||||
if(iSpeedLimit==8) i=2;
|
|
||||||
if(iSpeedLimit==16) i=3;
|
|
||||||
|
|
||||||
ComboBox_SetCurSel(hWC,i);
|
|
||||||
|
|
||||||
if(iUsePPF) CheckDlgButton(hW,IDC_USEPPF,TRUE); // ppf
|
|
||||||
SetDlgItemText(hW,IDC_PPFFILE,szPPF);
|
|
||||||
SetDlgItemText(hW,IDC_SUBFILE,szSUBF);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void OnCDROK(HWND hW)
|
|
||||||
{
|
|
||||||
int iA,iT,iL,iR;
|
|
||||||
HWND hWC=GetDlgItem(hW,IDC_RTYPE);
|
|
||||||
|
|
||||||
GetCDRInfos(hW,&iA,&iT,&iL);
|
|
||||||
if(iA==-1) return;
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_CACHE);
|
|
||||||
iUseCaching=ComboBox_GetCurSel(hWC);
|
|
||||||
if(iUseCaching<0) iUseCaching=0;
|
|
||||||
if(iUseCaching>4) iUseCaching=4;
|
|
||||||
|
|
||||||
iCD_AD=iA;iCD_TA=iT;iCD_LU=iL;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_SPEEDLIMIT))
|
|
||||||
iUseSpeedLimit=1;
|
|
||||||
else iUseSpeedLimit=0;
|
|
||||||
|
|
||||||
iUseSubReading=0;
|
|
||||||
hWC=GetDlgItem(hW,IDC_SUBCHAN0);
|
|
||||||
iUseSubReading=ComboBox_GetCurSel(hWC);
|
|
||||||
if(iUseSubReading<0) iUseSubReading=0;
|
|
||||||
if(iUseSubReading>2) iUseSubReading=2;
|
|
||||||
if(iUseSubReading==1) iUseCaching=0;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_DATACACHE))
|
|
||||||
iUseDataCache=1;
|
|
||||||
else iUseDataCache=0;
|
|
||||||
if(iUseCaching==0) iUseDataCache=0;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_NOWAIT))
|
|
||||||
iNoWait=1;
|
|
||||||
else iNoWait=0;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_TRAYSTATE))
|
|
||||||
iCheckTrayStatus=1;
|
|
||||||
else iCheckTrayStatus=0;
|
|
||||||
|
|
||||||
iMaxRetry=GetDlgItemInt(hW,IDC_RETRY,NULL,FALSE);
|
|
||||||
if(iMaxRetry<1) iMaxRetry=1;
|
|
||||||
if(iMaxRetry>10) iMaxRetry=10;
|
|
||||||
if(!IsDlgButtonChecked(hW,IDC_TRYAGAIN)) iMaxRetry=0;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_SHOWREADERR))
|
|
||||||
iShowReadErr=1;
|
|
||||||
else iShowReadErr=0;
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_SPEED);
|
|
||||||
iR=ComboBox_GetCurSel(hWC);
|
|
||||||
|
|
||||||
iSpeedLimit=2;
|
|
||||||
if(iR==1) iSpeedLimit=4;
|
|
||||||
if(iR==2) iSpeedLimit=8;
|
|
||||||
if(iR==3) iSpeedLimit=16;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_USEPPF))
|
|
||||||
iUsePPF=1;
|
|
||||||
else iUsePPF=0;
|
|
||||||
|
|
||||||
GetDlgItemText(hW,IDC_PPFFILE,szPPF,259);
|
|
||||||
GetDlgItemText(hW,IDC_SUBFILE,szSUBF,259);
|
|
||||||
|
|
||||||
WriteConfig(); // write registry
|
|
||||||
|
|
||||||
EndDialog(hW,TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void OnCDRCancel(HWND hW)
|
|
||||||
{
|
|
||||||
EndDialog(hW,FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL CALLBACK CDRDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch(uMsg)
|
|
||||||
{
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
return OnInitCDRDialog(hW);
|
|
||||||
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
|
||||||
switch(LOWORD(wParam))
|
|
||||||
{
|
|
||||||
case IDC_SUBCHAN0: if(HIWORD(wParam)==CBN_SELCHANGE)
|
|
||||||
{ShowSubFileStuff(hW);return TRUE;}
|
|
||||||
case IDC_IMODE: if(HIWORD(wParam)==CBN_SELCHANGE)
|
|
||||||
{OnIMode(hW);return TRUE;}
|
|
||||||
break;
|
|
||||||
case IDC_CACHE: if(HIWORD(wParam)==CBN_SELCHANGE)
|
|
||||||
{OnCache(hW);return TRUE;}
|
|
||||||
break;
|
|
||||||
case IDCANCEL: OnCDRCancel(hW); return TRUE;
|
|
||||||
case IDOK: OnCDROK(hW); return TRUE;
|
|
||||||
case IDC_CHOOSEFILE: OnChooseFile(hW,0);return TRUE;
|
|
||||||
case IDC_CHOOSESUBF: OnChooseFile(hW,1);return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch(uMsg)
|
|
||||||
{
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
|
||||||
switch(LOWORD(wParam))
|
|
||||||
{
|
|
||||||
case IDCANCEL: EndDialog(hW,FALSE);return TRUE;
|
|
||||||
case IDOK: EndDialog(hW,FALSE);return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "CDVDlib.h"
|
|
||||||
#include "CDVDiso.h"
|
|
||||||
#include "CDVDisodrv.h"
|
|
||||||
|
|
||||||
int CheckDiskType(int baseType){
|
|
||||||
int f;
|
|
||||||
char buffer[256];//if a file is longer...it should be shorter :D
|
|
||||||
char *pos;
|
|
||||||
static struct TocEntry tocEntry;
|
|
||||||
|
|
||||||
CDVDFS_init();
|
|
||||||
|
|
||||||
// check if the file exists
|
|
||||||
if (CDVD_findfile("SYSTEM.CNF;1", &tocEntry) != TRUE){
|
|
||||||
if (CDVD_findfile("VIDEO_TS/VIDEO_TS.IFO;1", &tocEntry) != TRUE)
|
|
||||||
if (CDVD_findfile("PSX.EXE;1", &tocEntry) != TRUE)
|
|
||||||
return CDVD_TYPE_ILLEGAL;
|
|
||||||
else
|
|
||||||
return CDVD_TYPE_PSCD;
|
|
||||||
else
|
|
||||||
return CDVD_TYPE_DVDV;
|
|
||||||
}
|
|
||||||
|
|
||||||
f=CDVDFS_open("SYSTEM.CNF;1", 1);
|
|
||||||
CDVDFS_read(f, buffer, 256);
|
|
||||||
CDVDFS_close(f);
|
|
||||||
|
|
||||||
buffer[tocEntry.fileSize]='\0';
|
|
||||||
|
|
||||||
pos=strstr(buffer, "BOOT2");
|
|
||||||
if (pos==NULL){
|
|
||||||
pos=strstr(buffer, "BOOT");
|
|
||||||
if (pos==NULL) {
|
|
||||||
return CDVD_TYPE_ILLEGAL;
|
|
||||||
}
|
|
||||||
return CDVD_TYPE_PSCD;
|
|
||||||
}
|
|
||||||
return (baseType==CDVD_TYPE_DETCTCD)?CDVD_TYPE_PS2CD:CDVD_TYPE_PS2DVD;
|
|
||||||
}
|
|
|
@ -1,383 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
ioctrl.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_IOCTL
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HANDLE hIOCTL=NULL; // global drive file handle
|
|
||||||
DWORD dwIOCTLAttr=0; // open attribute
|
|
||||||
OVERLAPPED ovcIOCTL; // global overlapped struct
|
|
||||||
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptIOCTL; // global read bufs
|
|
||||||
RAW_READ_INFO rawIOCTL;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// open drive
|
|
||||||
|
|
||||||
void OpenIOCTLHandle(int iA,int iT,int iL)
|
|
||||||
{
|
|
||||||
char cLetter;
|
|
||||||
|
|
||||||
if(hIOCTL) return;
|
|
||||||
|
|
||||||
cLetter=MapIOCTLDriveLetter(iA,iT,iL); // get drive
|
|
||||||
|
|
||||||
if(!cLetter) return;
|
|
||||||
|
|
||||||
hIOCTL=OpenIOCTLFile(cLetter, // open drive
|
|
||||||
(iUseCaching==2)?TRUE:FALSE); // (caching:2 -> overlapped)
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// close drive
|
|
||||||
|
|
||||||
void CloseIOCTLHandle(void)
|
|
||||||
{
|
|
||||||
if(hIOCTL) CloseHandle(hIOCTL);
|
|
||||||
hIOCTL=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// get drive letter by a,t,l
|
|
||||||
|
|
||||||
char MapIOCTLDriveLetter(int iA,int iT,int iL)
|
|
||||||
{
|
|
||||||
char cLetter[4];int iDA,iDT,iDL;HANDLE hF;
|
|
||||||
|
|
||||||
strcpy(cLetter,"C:\\");
|
|
||||||
|
|
||||||
for(cLetter[0]='C';cLetter[0]<='Z';cLetter[0]++)
|
|
||||||
{
|
|
||||||
if(GetDriveType(cLetter)==DRIVE_CDROM)
|
|
||||||
{
|
|
||||||
hF=OpenIOCTLFile(cLetter[0],FALSE);
|
|
||||||
GetIOCTLAdapter(hF,&iDA,&iDT,&iDL);
|
|
||||||
CloseHandle(hF);
|
|
||||||
if(iA==iDA && iT==iDT && iL==iDL)
|
|
||||||
return cLetter[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// get cd drive list, using ioctl, not aspi
|
|
||||||
|
|
||||||
int GetIOCTLCDDrives(char * pDList)
|
|
||||||
{
|
|
||||||
char cLetter[4];int iDA,iDT,iDL;HANDLE hF;
|
|
||||||
int iCnt=0;char * p=pDList;
|
|
||||||
|
|
||||||
strcpy(cLetter,"C:\\");
|
|
||||||
|
|
||||||
for(cLetter[0]='C';cLetter[0]<='Z';cLetter[0]++)
|
|
||||||
{
|
|
||||||
if(GetDriveType(cLetter)==DRIVE_CDROM)
|
|
||||||
{
|
|
||||||
hF=OpenIOCTLFile(cLetter[0],FALSE);
|
|
||||||
GetIOCTLAdapter(hF,&iDA,&iDT,&iDL);
|
|
||||||
CloseHandle(hF);
|
|
||||||
if(iDA!=-1 && iDT!=-1 && iDL!=-1)
|
|
||||||
{
|
|
||||||
wsprintf(p,"[%d:%d:%d] Drive %c:",
|
|
||||||
iDA,iDT,iDL,cLetter[0]);
|
|
||||||
p+=strlen(p)+1;
|
|
||||||
iCnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return iCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// open drive in sync/async mode
|
|
||||||
|
|
||||||
HANDLE OpenIOCTLFile(char cLetter,BOOL bAsync)
|
|
||||||
{
|
|
||||||
HANDLE hF;char szFName[16];
|
|
||||||
OSVERSIONINFO ov;DWORD dwFlags;
|
|
||||||
|
|
||||||
if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED;
|
|
||||||
else dwIOCTLAttr=0;
|
|
||||||
|
|
||||||
memset(&ov,0,sizeof(OSVERSIONINFO));
|
|
||||||
ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
|
|
||||||
GetVersionEx(&ov);
|
|
||||||
|
|
||||||
if((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) &&
|
|
||||||
(ov.dwMajorVersion>4))
|
|
||||||
dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP
|
|
||||||
else dwFlags = GENERIC_READ;
|
|
||||||
|
|
||||||
wsprintf(szFName, "\\\\.\\%c:",cLetter);
|
|
||||||
|
|
||||||
hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive
|
|
||||||
NULL,OPEN_EXISTING,dwIOCTLAttr,NULL);
|
|
||||||
|
|
||||||
if(hF==INVALID_HANDLE_VALUE) // mmm... no success?
|
|
||||||
{
|
|
||||||
dwFlags^=GENERIC_WRITE; // -> try write toggle
|
|
||||||
hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again
|
|
||||||
NULL,OPEN_EXISTING,dwIOCTLAttr,NULL);
|
|
||||||
if(hF==INVALID_HANDLE_VALUE) return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// get a,t,l
|
|
||||||
|
|
||||||
void GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL)
|
|
||||||
{
|
|
||||||
char szBuf[1024];PSCSI_ADDRESS pSA;DWORD dwRet;
|
|
||||||
|
|
||||||
*iDA=*iDT=*iDL=-1;
|
|
||||||
if(hF==NULL) return;
|
|
||||||
|
|
||||||
memset(szBuf,0,1024);
|
|
||||||
|
|
||||||
pSA=(PSCSI_ADDRESS)szBuf;
|
|
||||||
pSA->Length=sizeof(SCSI_ADDRESS);
|
|
||||||
|
|
||||||
if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL,
|
|
||||||
0,pSA,sizeof(SCSI_ADDRESS),
|
|
||||||
&dwRet,NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
*iDA = pSA->PortNumber;
|
|
||||||
*iDT = pSA->TargetId;
|
|
||||||
*iDL = pSA->Lun;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// we fake the aspi call in ioctl scsi mode
|
|
||||||
|
|
||||||
DWORD IOCTLSendASPI32Command(LPSRB pSRB)
|
|
||||||
{
|
|
||||||
LPSRB_ExecSCSICmd pSC;DWORD dwRet;BOOL bStat;
|
|
||||||
|
|
||||||
if(!pSRB) return SS_ERR;
|
|
||||||
|
|
||||||
if(hIOCTL==NULL ||
|
|
||||||
pSRB->SRB_Cmd!=SC_EXEC_SCSI_CMD) // we only fake exec aspi scsi commands
|
|
||||||
{
|
|
||||||
pSRB->SRB_Status=SS_ERR;
|
|
||||||
return SS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
pSC=(LPSRB_ExecSCSICmd)pSRB;
|
|
||||||
|
|
||||||
memset(&sptIOCTL,0,sizeof(sptIOCTL));
|
|
||||||
|
|
||||||
sptIOCTL.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
|
|
||||||
sptIOCTL.spt.CdbLength = pSC->SRB_CDBLen;
|
|
||||||
sptIOCTL.spt.DataTransferLength = pSC->SRB_BufLen;
|
|
||||||
sptIOCTL.spt.TimeOutValue = 60;
|
|
||||||
sptIOCTL.spt.DataBuffer = pSC->SRB_BufPointer;
|
|
||||||
sptIOCTL.spt.SenseInfoLength = 14;
|
|
||||||
sptIOCTL.spt.TargetId = pSC->SRB_Target;
|
|
||||||
sptIOCTL.spt.Lun = pSC->SRB_Lun;
|
|
||||||
sptIOCTL.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
|
|
||||||
if(pSC->SRB_Flags&SRB_DIR_IN) sptIOCTL.spt.DataIn = SCSI_IOCTL_DATA_IN;
|
|
||||||
else if(pSC->SRB_Flags&SRB_DIR_OUT) sptIOCTL.spt.DataIn = SCSI_IOCTL_DATA_OUT;
|
|
||||||
else sptIOCTL.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
|
|
||||||
memcpy(sptIOCTL.spt.Cdb,pSC->CDBByte,pSC->SRB_CDBLen);
|
|
||||||
|
|
||||||
if(dwIOCTLAttr==FILE_FLAG_OVERLAPPED) // async?
|
|
||||||
{
|
|
||||||
ovcIOCTL.Internal=0;
|
|
||||||
ovcIOCTL.InternalHigh=0;
|
|
||||||
ovcIOCTL.Offset=0;
|
|
||||||
ovcIOCTL.OffsetHigh=0;
|
|
||||||
ovcIOCTL.hEvent=hEvent;
|
|
||||||
bStat = DeviceIoControl(hIOCTL,
|
|
||||||
IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
|
||||||
&sptIOCTL,
|
|
||||||
sizeof(sptIOCTL),
|
|
||||||
&sptIOCTL,
|
|
||||||
sizeof(sptIOCTL),
|
|
||||||
&dwRet,
|
|
||||||
&ovcIOCTL);
|
|
||||||
}
|
|
||||||
else // sync?
|
|
||||||
{
|
|
||||||
bStat = DeviceIoControl(hIOCTL,
|
|
||||||
IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
|
||||||
&sptIOCTL,
|
|
||||||
sizeof(sptIOCTL),
|
|
||||||
&sptIOCTL,
|
|
||||||
sizeof(sptIOCTL),
|
|
||||||
&dwRet,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bStat) // some err?
|
|
||||||
{
|
|
||||||
DWORD dwErrCode;
|
|
||||||
dwErrCode=GetLastError();
|
|
||||||
if(dwErrCode==ERROR_IO_PENDING) // -> pending?
|
|
||||||
{
|
|
||||||
pSC->SRB_Status=SS_COMP; // --> ok
|
|
||||||
return SS_PENDING;
|
|
||||||
}
|
|
||||||
pSC->SRB_Status=SS_ERR; // -> else error
|
|
||||||
return SS_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
pSC->SRB_Status=SS_COMP;
|
|
||||||
return SS_COMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// special raw mode... works on TEAC532S, for example
|
|
||||||
|
|
||||||
DWORD ReadIOCTL_Raw(BOOL bWait,FRAMEBUF * f)
|
|
||||||
{
|
|
||||||
DWORD dwRet;BOOL bStat;
|
|
||||||
|
|
||||||
if(hIOCTL==NULL) return SS_ERR;
|
|
||||||
|
|
||||||
rawIOCTL.DiskOffset.QuadPart = f->dwFrame*2048; // 2048 is needed here
|
|
||||||
rawIOCTL.SectorCount = f->dwFrameCnt;
|
|
||||||
rawIOCTL.TrackMode = XAForm2;//CDDA;//YellowMode2;//XAForm2;
|
|
||||||
|
|
||||||
if(dwIOCTLAttr==FILE_FLAG_OVERLAPPED) // async?
|
|
||||||
{
|
|
||||||
ovcIOCTL.Internal=0;
|
|
||||||
ovcIOCTL.InternalHigh=0;
|
|
||||||
ovcIOCTL.Offset=0;
|
|
||||||
ovcIOCTL.OffsetHigh=0;
|
|
||||||
ovcIOCTL.hEvent=hEvent;
|
|
||||||
ResetEvent(hEvent);
|
|
||||||
bStat = DeviceIoControl(hIOCTL,
|
|
||||||
IOCTL_CDROM_RAW_READ,
|
|
||||||
&rawIOCTL,sizeof(RAW_READ_INFO),
|
|
||||||
&(f->BufData[0]),f->dwBufLen,//2048,
|
|
||||||
&dwRet, &ovcIOCTL);
|
|
||||||
}
|
|
||||||
else // sync?
|
|
||||||
{
|
|
||||||
bStat = DeviceIoControl(hIOCTL,
|
|
||||||
IOCTL_CDROM_RAW_READ,
|
|
||||||
&rawIOCTL,sizeof(RAW_READ_INFO),
|
|
||||||
&(f->BufData[0]),f->dwBufLen,//2048,
|
|
||||||
&dwRet,NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bStat)
|
|
||||||
{
|
|
||||||
DWORD dwErrCode;
|
|
||||||
dwErrCode=GetLastError();
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("errorcode %d\n", dwErrCode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(dwErrCode==ERROR_IO_PENDING)
|
|
||||||
{
|
|
||||||
// we do a wait here, not later... no real async mode anyway
|
|
||||||
// bDoWaiting=TRUE;
|
|
||||||
|
|
||||||
WaitGenEvent(0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sx.SRB_Status=SS_ERR;
|
|
||||||
return SS_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sx.SRB_Status=SS_COMP;
|
|
||||||
return SS_COMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// special raw + special sub... dunno if this really
|
|
||||||
// works on any drive (teac is working, but giving unprecise
|
|
||||||
// subdata)
|
|
||||||
|
|
||||||
DWORD ReadIOCTL_Raw_Sub(BOOL bWait,FRAMEBUF * f)
|
|
||||||
{
|
|
||||||
DWORD dwRet;BOOL bStat;
|
|
||||||
SUB_Q_CHANNEL_DATA qd;unsigned char * p;
|
|
||||||
CDROM_SUB_Q_DATA_FORMAT qf;
|
|
||||||
|
|
||||||
if(hIOCTL==NULL) return SS_ERR;
|
|
||||||
|
|
||||||
rawIOCTL.DiskOffset.QuadPart = f->dwFrame*2048;
|
|
||||||
rawIOCTL.SectorCount = f->dwFrameCnt;
|
|
||||||
rawIOCTL.TrackMode = XAForm2;
|
|
||||||
|
|
||||||
bStat = DeviceIoControl(hIOCTL,
|
|
||||||
IOCTL_CDROM_RAW_READ,
|
|
||||||
&rawIOCTL,sizeof(RAW_READ_INFO),
|
|
||||||
&(f->BufData[0]),f->dwBufLen,
|
|
||||||
&dwRet,NULL);
|
|
||||||
|
|
||||||
if(!bStat) {sx.SRB_Status=SS_ERR;return SS_ERR;}
|
|
||||||
|
|
||||||
qf.Format=IOCTL_CDROM_CURRENT_POSITION;
|
|
||||||
qf.Track=1;
|
|
||||||
bStat = DeviceIoControl(hIOCTL,
|
|
||||||
IOCTL_CDROM_READ_Q_CHANNEL,
|
|
||||||
&qf,sizeof(CDROM_SUB_Q_DATA_FORMAT),
|
|
||||||
&qd,sizeof(SUB_Q_CHANNEL_DATA),
|
|
||||||
&dwRet,NULL);
|
|
||||||
|
|
||||||
p=(unsigned char*)&qd;
|
|
||||||
|
|
||||||
SubCData[12]=(p[5]<<4)|(p[5]>>4);
|
|
||||||
SubCData[13]=p[6];
|
|
||||||
SubCData[14]=p[7];
|
|
||||||
SubCData[15]=p[13];
|
|
||||||
SubCData[16]=p[14];
|
|
||||||
SubCData[17]=p[15];
|
|
||||||
SubCData[18]=0;
|
|
||||||
SubCData[19]=p[9];
|
|
||||||
SubCData[20]=p[10];
|
|
||||||
SubCData[21]=p[11];
|
|
||||||
|
|
||||||
SubCData[15]=itob(SubCData[15]);
|
|
||||||
SubCData[16]=itob(SubCData[16]);
|
|
||||||
SubCData[17]=itob(SubCData[17]);
|
|
||||||
|
|
||||||
SubCData[19]=itob(SubCData[19]);
|
|
||||||
SubCData[20]=itob(SubCData[20]);
|
|
||||||
SubCData[21]=itob(SubCData[21]);
|
|
||||||
|
|
||||||
if(!bStat) {sx.SRB_Status=SS_ERR;return SS_ERR;}
|
|
||||||
|
|
||||||
sx.SRB_Status=SS_COMP;
|
|
||||||
return SS_COMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,72 +0,0 @@
|
||||||
# Project: cdvdPeops
|
|
||||||
# Makefile created by Dev-C++ 4.9.9.0
|
|
||||||
|
|
||||||
CPP = g++.exe
|
|
||||||
CC = gcc.exe
|
|
||||||
WINDRES = windres.exe
|
|
||||||
RES = cdvdPeops_private.res
|
|
||||||
OBJ = Release/cdr.o Release/cdvdPeops.o Release/cfg.o Release/generic.o Release/ioctrl.o Release/ppf.o Release/read.o Release/scsi.o Release/StdAfx.o Release/sub.o Release/toc.o Release/cdda.o Release/i386.o $(RES)
|
|
||||||
LINKOBJ = Release/cdr.o Release/cdvdPeops.o Release/cfg.o Release/generic.o Release/ioctrl.o Release/ppf.o Release/read.o Release/scsi.o Release/StdAfx.o Release/sub.o Release/toc.o Release/cdda.o Release/i386.o $(RES)
|
|
||||||
LIBS = -L"D:/vs/Dev-Cpp/lib" -lkernel32 -luser32 -ladvapi32 -lcomdlg32 --add-stdcall-alias
|
|
||||||
INCS = -I"D:/vs/Dev-Cpp/include" -I"d:/vs/vc98/MFC/include"
|
|
||||||
CXXINCS = -I"D:/vs/Dev-Cpp/include/c++" -I"D:/vs/Dev-Cpp/include/c++/mingw32" -I"D:/vs/Dev-Cpp/include/c++/backward" -I"D:/vs/Dev-Cpp/include" -I"d:/vs/vc98/MFC/include"
|
|
||||||
BIN = ../../../emus/pcsx2_0.6/plugins/cdvdPeops.dll
|
|
||||||
CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -mcpu=pentium -D_M_IX86=500 -W -DWIN32 -DNDEBUG -D_WINDOWS -D_GCC -fexpensive-optimizations -O3
|
|
||||||
CFLAGS = $(INCS) -D__GNUWIN32__ -mcpu=pentium -D_M_IX86=500 -W -DWIN32 -DNDEBUG -D_WINDOWS -D_GCC -fexpensive-optimizations -O3
|
|
||||||
|
|
||||||
.PHONY: all all-before all-after clean clean-custom
|
|
||||||
|
|
||||||
all: all-before ../../../emus/pcsx2_0.6/plugins/cdvdPeops.dll all-after
|
|
||||||
|
|
||||||
|
|
||||||
clean: clean-custom
|
|
||||||
rm -f $(OBJ) $(BIN)
|
|
||||||
|
|
||||||
DLLWRAP=dllwrap.exe
|
|
||||||
DEFFILE=../../../emus/pcsx2_0.6/plugins/libcdvdPeops.def
|
|
||||||
STATICLIB=../../../emus/pcsx2_0.6/plugins/libcdvdPeops.a
|
|
||||||
|
|
||||||
$(BIN): $(LINKOBJ)
|
|
||||||
$(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
|
|
||||||
|
|
||||||
Release/cdr.o: cdr.c
|
|
||||||
$(CC) -c cdr.c -o Release/cdr.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/cdvdPeops.o: cdvdPeops.c
|
|
||||||
$(CC) -c cdvdPeops.c -o Release/cdvdPeops.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/cfg.o: cfg.c
|
|
||||||
$(CC) -c cfg.c -o Release/cfg.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/generic.o: generic.c
|
|
||||||
$(CC) -c generic.c -o Release/generic.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/ioctrl.o: ioctrl.c
|
|
||||||
$(CC) -c ioctrl.c -o Release/ioctrl.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/ppf.o: ppf.c
|
|
||||||
$(CC) -c ppf.c -o Release/ppf.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/read.o: read.c
|
|
||||||
$(CC) -c read.c -o Release/read.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/scsi.o: scsi.c
|
|
||||||
$(CC) -c scsi.c -o Release/scsi.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/StdAfx.o: StdAfx.c
|
|
||||||
$(CC) -c StdAfx.c -o Release/StdAfx.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/sub.o: sub.c
|
|
||||||
$(CC) -c sub.c -o Release/sub.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/toc.o: toc.c
|
|
||||||
$(CC) -c toc.c -o Release/toc.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/cdda.o: cdda.c
|
|
||||||
$(CC) -c cdda.c -o Release/cdda.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/i386.o: i386.asm
|
|
||||||
nasmw.exe -f win32 -D__WIN32__ -D__i386__ i386.asm -o release\i386.o
|
|
||||||
|
|
||||||
cdvdPeops_private.res: cdvdPeops_private.rc ../../../src/cdvdPeops/src/cdvdPeops.rc
|
|
||||||
$(WINDRES) -i cdvdPeops_private.rc -I rc -o cdvdPeops_private.res -O coff
|
|
|
@ -1,789 +0,0 @@
|
||||||
#ifndef __PS2EDEFS_H__
|
|
||||||
#define __PS2EDEFS_H__
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PS2E Definitions v0.6.2 (beta)
|
|
||||||
*
|
|
||||||
* Author: linuzappz@hotmail.com
|
|
||||||
* shadowpcsx2@yahoo.gr
|
|
||||||
* florinsasu@hotmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Notes:
|
|
||||||
* Since this is still beta things may change.
|
|
||||||
|
|
||||||
* OSflags:
|
|
||||||
__linux__ (linux OS)
|
|
||||||
__WIN32__ (win32 OS)
|
|
||||||
|
|
||||||
* common return values (for ie. GSinit):
|
|
||||||
0 - success
|
|
||||||
-1 - error
|
|
||||||
|
|
||||||
* reserved keys:
|
|
||||||
F1 to F10 are reserved for the emulator
|
|
||||||
|
|
||||||
* plugins should NOT change the current
|
|
||||||
working directory.
|
|
||||||
(on win32, add flag OFN_NOCHANGEDIR for
|
|
||||||
GetOpenFileName)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PS2Etypes.h"
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#define CALLBACK
|
|
||||||
#else
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* common defines */
|
|
||||||
|
|
||||||
#if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) || \
|
|
||||||
defined(SPU2defs) || defined(CDVDdefs) || defined(DEV9defs) || \
|
|
||||||
defined(USBdefs) || defined(FWdefs)
|
|
||||||
#define COMMONdefs
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PS2EgetLibType returns (may be OR'd)
|
|
||||||
#define PS2E_LT_GS 0x01
|
|
||||||
#define PS2E_LT_PAD 0x02 // -=[ OBSOLETE ]=-
|
|
||||||
#define PS2E_LT_SPU2 0x04
|
|
||||||
#define PS2E_LT_CDVD 0x08
|
|
||||||
#define PS2E_LT_DEV9 0x10
|
|
||||||
#define PS2E_LT_USB 0x20
|
|
||||||
#define PS2E_LT_FW 0x40
|
|
||||||
#define PS2E_LT_SIO 0x80
|
|
||||||
|
|
||||||
// PS2EgetLibVersion2 (high 16 bits)
|
|
||||||
#define PS2E_GS_VERSION 0x0006
|
|
||||||
#define PS2E_PAD_VERSION 0x0002 // -=[ OBSOLETE ]=-
|
|
||||||
#define PS2E_SPU2_VERSION 0x0004
|
|
||||||
#define PS2E_CDVD_VERSION 0x0005
|
|
||||||
#define PS2E_DEV9_VERSION 0x0003
|
|
||||||
#define PS2E_USB_VERSION 0x0003
|
|
||||||
#define PS2E_FW_VERSION 0x0002
|
|
||||||
#define PS2E_SIO_VERSION 0x0001
|
|
||||||
#ifdef COMMONdefs
|
|
||||||
|
|
||||||
u32 CALLBACK PS2EgetLibType(void);
|
|
||||||
u32 CALLBACK PS2EgetLibVersion2(u32 type);
|
|
||||||
char* CALLBACK PS2EgetLibName(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// key values:
|
|
||||||
/* key values must be OS dependant:
|
|
||||||
win32: the VK_XXX will be used (WinUser)
|
|
||||||
linux: the XK_XXX will be used (XFree86)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// event values:
|
|
||||||
#define KEYPRESS 1
|
|
||||||
#define KEYRELEASE 2
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u32 key;
|
|
||||||
u32 event;
|
|
||||||
} keyEvent;
|
|
||||||
|
|
||||||
// plugin types
|
|
||||||
#define SIO_TYPE_PAD 0x00000001
|
|
||||||
#define SIO_TYPE_MTAP 0x00000004
|
|
||||||
#define SIO_TYPE_RM 0x00000040
|
|
||||||
#define SIO_TYPE_MC 0x00000100
|
|
||||||
|
|
||||||
typedef int (CALLBACK * SIOchangeSlotCB)(int slot);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 ctrl:4; // control and mode bits
|
|
||||||
u8 mode:4; // control and mode bits
|
|
||||||
u8 trackNum; // current track number (1 to 99)
|
|
||||||
u8 trackIndex; // current index within track (0 to 99)
|
|
||||||
u8 trackM; // current minute location on the disc (BCD encoded)
|
|
||||||
u8 trackS; // current sector location on the disc (BCD encoded)
|
|
||||||
u8 trackF; // current frame location on the disc (BCD encoded)
|
|
||||||
u8 pad; // unused
|
|
||||||
u8 discM; // current minute offset from first track (BCD encoded)
|
|
||||||
u8 discS; // current sector offset from first track (BCD encoded)
|
|
||||||
u8 discF; // current frame offset from first track (BCD encoded)
|
|
||||||
} cdvdSubQ;
|
|
||||||
|
|
||||||
typedef struct { // NOT bcd coded
|
|
||||||
u32 lsn;
|
|
||||||
u8 type;
|
|
||||||
} cdvdTD;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 strack; //number of the first track (usually 1)
|
|
||||||
u8 etrack; //number of the last track
|
|
||||||
} cdvdTN;
|
|
||||||
|
|
||||||
// CDVDreadTrack mode values:
|
|
||||||
#define CDVD_MODE_2352 0 // full 2352 bytes
|
|
||||||
#define CDVD_MODE_2340 1 // skip sync (12) bytes
|
|
||||||
#define CDVD_MODE_2328 2 // skip sync+head+sub (24) bytes
|
|
||||||
#define CDVD_MODE_2048 3 // skip sync+head+sub (24) bytes
|
|
||||||
#define CDVD_MODE_2368 4 // full 2352 bytes + 16 subq
|
|
||||||
|
|
||||||
// CDVDgetDiskType returns:
|
|
||||||
#define CDVD_TYPE_ILLEGAL 0xff // Illegal Disc
|
|
||||||
#define CDVD_TYPE_DVDV 0xfe // DVD Video
|
|
||||||
#define CDVD_TYPE_CDDA 0xfd // Audio CD
|
|
||||||
#define CDVD_TYPE_PS2DVD 0x14 // PS2 DVD
|
|
||||||
#define CDVD_TYPE_PS2CDDA 0x13 // PS2 CD (with audio)
|
|
||||||
#define CDVD_TYPE_PS2CD 0x12 // PS2 CD
|
|
||||||
#define CDVD_TYPE_PSCDDA 0x11 // PS CD (with audio)
|
|
||||||
#define CDVD_TYPE_PSCD 0x10 // PS CD
|
|
||||||
#define CDVD_TYPE_UNKNOWN 0x05 // Unknown
|
|
||||||
#define CDVD_TYPE_DETCTDVDD 0x04 // Detecting Dvd Dual Sided
|
|
||||||
#define CDVD_TYPE_DETCTDVDS 0x03 // Detecting Dvd Single Sided
|
|
||||||
#define CDVD_TYPE_DETCTCD 0x02 // Detecting Cd
|
|
||||||
#define CDVD_TYPE_DETCT 0x01 // Detecting
|
|
||||||
#define CDVD_TYPE_NODISC 0x00 // No Disc
|
|
||||||
|
|
||||||
// CDVDgetTrayStatus returns:
|
|
||||||
#define CDVD_TRAY_CLOSE 0x00
|
|
||||||
#define CDVD_TRAY_OPEN 0x01
|
|
||||||
|
|
||||||
// cdvdTD.type (track types for cds)
|
|
||||||
#define CDVD_AUDIO_TRACK 0x01
|
|
||||||
#define CDVD_MODE1_TRACK 0x41
|
|
||||||
#define CDVD_MODE2_TRACK 0x61
|
|
||||||
|
|
||||||
#define CDVD_AUDIO_MASK 0x00
|
|
||||||
#define CDVD_DATA_MASK 0x40
|
|
||||||
// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel)
|
|
||||||
|
|
||||||
typedef void (*DEV9callback)(int cycles);
|
|
||||||
typedef int (*DEV9handler)(void);
|
|
||||||
|
|
||||||
typedef void (*USBcallback)(int cycles);
|
|
||||||
typedef int (*USBhandler)(void);
|
|
||||||
|
|
||||||
// freeze modes:
|
|
||||||
#define FREEZE_LOAD 0
|
|
||||||
#define FREEZE_SAVE 1
|
|
||||||
#define FREEZE_SIZE 2
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int size;
|
|
||||||
s8 *data;
|
|
||||||
} freezeData;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[8];
|
|
||||||
void *common;
|
|
||||||
} GSdriverInfo;
|
|
||||||
|
|
||||||
#ifdef __WIN32__
|
|
||||||
typedef struct { // unsupported values must be set to zero
|
|
||||||
HWND hWnd;
|
|
||||||
HMENU hMenu;
|
|
||||||
HWND hStatusWnd;
|
|
||||||
} winInfo;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* GS plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef GSdefs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK GSinit();
|
|
||||||
s32 CALLBACK GSopen(void *pDsp, char *Title);
|
|
||||||
void CALLBACK GSclose();
|
|
||||||
void CALLBACK GSshutdown();
|
|
||||||
void CALLBACK GSvsync();
|
|
||||||
void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr);
|
|
||||||
void CALLBACK GSgifTransfer2(u32 *pMem, u32 size);
|
|
||||||
void CALLBACK GSgifTransfer3(u32 *pMem, u32 size);
|
|
||||||
void CALLBACK GSwrite8(u32 mem, u8 value);
|
|
||||||
void CALLBACK GSwrite16(u32 mem, u16 value);
|
|
||||||
void CALLBACK GSwrite32(u32 mem, u32 value);
|
|
||||||
void CALLBACK GSwrite64(u32 mem, u64 value);
|
|
||||||
u8 CALLBACK GSread8(u32 mem);
|
|
||||||
u16 CALLBACK GSread16(u32 mem);
|
|
||||||
u32 CALLBACK GSread32(u32 mem);
|
|
||||||
u64 CALLBACK GSread64(u32 mem);
|
|
||||||
void CALLBACK GSreadFIFO(u64 *mem);
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
// GSkeyEvent gets called when there is a keyEvent from the PAD plugin
|
|
||||||
void CALLBACK GSkeyEvent(keyEvent *ev);
|
|
||||||
void CALLBACK GSmakeSnapshot(char *path);
|
|
||||||
void CALLBACK GSirqCallback(void (*callback)());
|
|
||||||
void CALLBACK GSprintf(int timeout, char *fmt, ...);
|
|
||||||
void CALLBACK GSsetCSR(u64 *csr);
|
|
||||||
void CALLBACK GSgetDriverInfo(GSdriverInfo *info);
|
|
||||||
#ifdef __WIN32__
|
|
||||||
s32 CALLBACK GSsetWindowInfo(winInfo *info);
|
|
||||||
#endif
|
|
||||||
s32 CALLBACK GSfreeze(int mode, freezeData *data);
|
|
||||||
void CALLBACK GSconfigure();
|
|
||||||
void CALLBACK GSabout();
|
|
||||||
s32 CALLBACK GStest();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PAD plugin API -=[ OBSOLETE ]=- */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef PADdefs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK PADinit(u32 flags);
|
|
||||||
s32 CALLBACK PADopen(void *pDsp);
|
|
||||||
void CALLBACK PADclose();
|
|
||||||
void CALLBACK PADshutdown();
|
|
||||||
// PADkeyEvent is called every vsync (return NULL if no event)
|
|
||||||
keyEvent* CALLBACK PADkeyEvent();
|
|
||||||
u8 CALLBACK PADstartPoll(int pad);
|
|
||||||
u8 CALLBACK PADpoll(u8 value);
|
|
||||||
// returns: 1 if supported pad1
|
|
||||||
// 2 if supported pad2
|
|
||||||
// 3 if both are supported
|
|
||||||
u32 CALLBACK PADquery();
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
void CALLBACK PADgsDriverInfo(GSdriverInfo *info);
|
|
||||||
void CALLBACK PADconfigure();
|
|
||||||
void CALLBACK PADabout();
|
|
||||||
s32 CALLBACK PADtest();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SIO plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef SIOdefs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK SIOinit(u32 port, u32 slot, SIOchangeSlotCB f);
|
|
||||||
s32 CALLBACK SIOopen(void *pDsp);
|
|
||||||
void CALLBACK SIOclose();
|
|
||||||
void CALLBACK SIOshutdown();
|
|
||||||
u8 CALLBACK SIOstartPoll(u8 value);
|
|
||||||
u8 CALLBACK SIOpoll(u8 value);
|
|
||||||
// returns: SIO_TYPE_{PAD,MTAP,RM,MC}
|
|
||||||
u32 CALLBACK SIOquery();
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
void CALLBACK SIOconfigure();
|
|
||||||
void CALLBACK SIOabout();
|
|
||||||
s32 CALLBACK SIOtest();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SPU2 plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef SPU2defs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK SPU2init();
|
|
||||||
s32 CALLBACK SPU2open(void *pDsp);
|
|
||||||
void CALLBACK SPU2close();
|
|
||||||
void CALLBACK SPU2shutdown();
|
|
||||||
void CALLBACK SPU2write(u32 mem, u16 value);
|
|
||||||
u16 CALLBACK SPU2read(u32 mem);
|
|
||||||
void CALLBACK SPU2readDMA4Mem(u16 *pMem, int size);
|
|
||||||
void CALLBACK SPU2writeDMA4Mem(u16 *pMem, int size);
|
|
||||||
void CALLBACK SPU2interruptDMA4();
|
|
||||||
void CALLBACK SPU2readDMA7Mem(u16* pMem, int size);
|
|
||||||
void CALLBACK SPU2writeDMA7Mem(u16 *pMem, int size);
|
|
||||||
void CALLBACK SPU2interruptDMA7();
|
|
||||||
void CALLBACK SPU2irqCallback(void (*callback)());
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
void CALLBACK SPU2async(u32 cycles);
|
|
||||||
s32 CALLBACK SPU2freeze(int mode, freezeData *data);
|
|
||||||
void CALLBACK SPU2configure();
|
|
||||||
void CALLBACK SPU2about();
|
|
||||||
s32 CALLBACK SPU2test();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* CDVD plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef CDVDdefs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK CDVDinit();
|
|
||||||
s32 CALLBACK CDVDopen();
|
|
||||||
void CALLBACK CDVDclose();
|
|
||||||
void CALLBACK CDVDshutdown();
|
|
||||||
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode);
|
|
||||||
|
|
||||||
// return can be NULL (for async modes)
|
|
||||||
u8* CALLBACK CDVDgetBuffer();
|
|
||||||
|
|
||||||
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data)
|
|
||||||
s32 CALLBACK CDVDgetTN(cdvdTN *Buffer); //disk information
|
|
||||||
s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type
|
|
||||||
s32 CALLBACK CDVDgetTOC(void* toc); //gets ps2 style toc from disc
|
|
||||||
s32 CALLBACK CDVDgetDiskType(); //CDVD_TYPE_xxxx
|
|
||||||
s32 CALLBACK CDVDgetTrayStatus(); //CDVD_TRAY_xxxx
|
|
||||||
s32 CALLBACK CDVDctrlTrayOpen(); //open disc tray
|
|
||||||
s32 CALLBACK CDVDctrlTrayClose(); //close disc tray
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
void CALLBACK CDVDconfigure();
|
|
||||||
void CALLBACK CDVDabout();
|
|
||||||
s32 CALLBACK CDVDtest();
|
|
||||||
void CALLBACK CDVDnewDiskCB(void (*callback)());
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* DEV9 plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef DEV9defs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK DEV9init();
|
|
||||||
s32 CALLBACK DEV9open(void *pDsp);
|
|
||||||
void CALLBACK DEV9close();
|
|
||||||
void CALLBACK DEV9shutdown();
|
|
||||||
u8 CALLBACK DEV9read8(u32 addr);
|
|
||||||
u16 CALLBACK DEV9read16(u32 addr);
|
|
||||||
u32 CALLBACK DEV9read32(u32 addr);
|
|
||||||
void CALLBACK DEV9write8(u32 addr, u8 value);
|
|
||||||
void CALLBACK DEV9write16(u32 addr, u16 value);
|
|
||||||
void CALLBACK DEV9write32(u32 addr, u32 value);
|
|
||||||
void CALLBACK DEV9readDMA8Mem(u32 *pMem, int size);
|
|
||||||
void CALLBACK DEV9writeDMA8Mem(u32 *pMem, int size);
|
|
||||||
// cycles = IOP cycles before calling callback,
|
|
||||||
// if callback returns 1 the irq is triggered, else not
|
|
||||||
void CALLBACK DEV9irqCallback(DEV9callback callback);
|
|
||||||
DEV9handler CALLBACK DEV9irqHandler(void);
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
s32 CALLBACK DEV9freeze(int mode, freezeData *data);
|
|
||||||
void CALLBACK DEV9configure();
|
|
||||||
void CALLBACK DEV9about();
|
|
||||||
s32 CALLBACK DEV9test();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* USB plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef USBdefs
|
|
||||||
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK USBinit();
|
|
||||||
s32 CALLBACK USBopen(void *pDsp);
|
|
||||||
void CALLBACK USBclose();
|
|
||||||
void CALLBACK USBshutdown();
|
|
||||||
u8 CALLBACK USBread8(u32 addr);
|
|
||||||
u16 CALLBACK USBread16(u32 addr);
|
|
||||||
u32 CALLBACK USBread32(u32 addr);
|
|
||||||
void CALLBACK USBwrite8(u32 addr, u8 value);
|
|
||||||
void CALLBACK USBwrite16(u32 addr, u16 value);
|
|
||||||
void CALLBACK USBwrite32(u32 addr, u32 value);
|
|
||||||
// cycles = IOP cycles before calling callback,
|
|
||||||
// if callback returns 1 the irq is triggered, else not
|
|
||||||
void CALLBACK USBirqCallback(USBcallback callback);
|
|
||||||
USBhandler CALLBACK USBirqHandler(void);
|
|
||||||
void CALLBACK USBsetRAM(void *mem);
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
s32 CALLBACK USBfreeze(int mode, freezeData *data);
|
|
||||||
void CALLBACK USBconfigure();
|
|
||||||
void CALLBACK USBabout();
|
|
||||||
s32 CALLBACK USBtest();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* FW plugin API */
|
|
||||||
|
|
||||||
// if this file is included with this define
|
|
||||||
// the next api will not be skipped by the compiler
|
|
||||||
#ifdef FWdefs
|
|
||||||
// basic funcs
|
|
||||||
|
|
||||||
s32 CALLBACK FWinit();
|
|
||||||
s32 CALLBACK FWopen(void *pDsp);
|
|
||||||
void CALLBACK FWclose();
|
|
||||||
void CALLBACK FWshutdown();
|
|
||||||
u32 CALLBACK FWread32(u32 addr);
|
|
||||||
void CALLBACK FWwrite32(u32 addr, u32 value);
|
|
||||||
void CALLBACK FWirqCallback(void (*callback)());
|
|
||||||
|
|
||||||
// extended funcs
|
|
||||||
|
|
||||||
s32 CALLBACK FWfreeze(int mode, freezeData *data);
|
|
||||||
void CALLBACK FWconfigure();
|
|
||||||
void CALLBACK FWabout();
|
|
||||||
s32 CALLBACK FWtest();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// might be useful for emulators
|
|
||||||
#ifdef PLUGINtypedefs
|
|
||||||
|
|
||||||
typedef u32 (CALLBACK* _PS2EgetLibType)(void);
|
|
||||||
typedef u32 (CALLBACK* _PS2EgetLibVersion2)(u32 type);
|
|
||||||
typedef char*(CALLBACK* _PS2EgetLibName)(void);
|
|
||||||
|
|
||||||
// GS
|
|
||||||
typedef s32 (CALLBACK* _GSinit)();
|
|
||||||
typedef s32 (CALLBACK* _GSopen)(void *pDsp, char *Title);
|
|
||||||
typedef void (CALLBACK* _GSclose)();
|
|
||||||
typedef void (CALLBACK* _GSshutdown)();
|
|
||||||
typedef void (CALLBACK* _GSvsync)();
|
|
||||||
typedef void (CALLBACK* _GSwrite8)(u32 mem, u8 value);
|
|
||||||
typedef void (CALLBACK* _GSwrite16)(u32 mem, u16 value);
|
|
||||||
typedef void (CALLBACK* _GSwrite32)(u32 mem, u32 value);
|
|
||||||
typedef void (CALLBACK* _GSwrite64)(u32 mem, u64 value);
|
|
||||||
typedef u8 (CALLBACK* _GSread8)(u32 mem);
|
|
||||||
typedef u16 (CALLBACK* _GSread16)(u32 mem);
|
|
||||||
typedef u32 (CALLBACK* _GSread32)(u32 mem);
|
|
||||||
typedef u64 (CALLBACK* _GSread64)(u32 mem);
|
|
||||||
typedef void (CALLBACK* _GSgifTransfer1)(u32 *pMem, u32 addr);
|
|
||||||
typedef void (CALLBACK* _GSgifTransfer2)(u32 *pMem, u32 size);
|
|
||||||
typedef void (CALLBACK* _GSgifTransfer3)(u32 *pMem, u32 size);
|
|
||||||
typedef void (CALLBACK* _GSreadFIFO)(u64 *pMem);
|
|
||||||
|
|
||||||
typedef void (CALLBACK* _GSkeyEvent)(keyEvent* ev);
|
|
||||||
typedef void (CALLBACK* _GSirqCallback)(void (*callback)());
|
|
||||||
typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...);
|
|
||||||
typedef void (CALLBACK* _GSsetCSR)(u64 * csr);
|
|
||||||
typedef void (CALLBACK* _GSgetDriverInfo)(GSdriverInfo *info);
|
|
||||||
#ifdef __WIN32__
|
|
||||||
typedef s32 (CALLBACK* _GSsetWindowInfo)(winInfo *info);
|
|
||||||
#endif
|
|
||||||
typedef void (CALLBACK* _GSmakeSnapshot)(char *path);
|
|
||||||
typedef s32 (CALLBACK* _GSfreeze)(int mode, freezeData *data);
|
|
||||||
typedef void (CALLBACK* _GSconfigure)();
|
|
||||||
typedef s32 (CALLBACK* _GStest)();
|
|
||||||
typedef void (CALLBACK* _GSabout)();
|
|
||||||
|
|
||||||
// PAD
|
|
||||||
typedef s32 (CALLBACK* _PADinit)(u32 flags);
|
|
||||||
typedef s32 (CALLBACK* _PADopen)(void *pDsp);
|
|
||||||
typedef void (CALLBACK* _PADclose)();
|
|
||||||
typedef void (CALLBACK* _PADshutdown)();
|
|
||||||
typedef keyEvent* (CALLBACK* _PADkeyEvent)();
|
|
||||||
typedef u8 (CALLBACK* _PADstartPoll)(int pad);
|
|
||||||
typedef u8 (CALLBACK* _PADpoll)(u8 value);
|
|
||||||
typedef u32 (CALLBACK* _PADquery)();
|
|
||||||
|
|
||||||
typedef void (CALLBACK* _PADgsDriverInfo)(GSdriverInfo *info);
|
|
||||||
typedef void (CALLBACK* _PADconfigure)();
|
|
||||||
typedef s32 (CALLBACK* _PADtest)();
|
|
||||||
typedef void (CALLBACK* _PADabout)();
|
|
||||||
|
|
||||||
// SIO
|
|
||||||
typedef s32 (CALLBACK* _SIOinit)(u32 port, u32 slot, SIOchangeSlotCB f);
|
|
||||||
typedef s32 (CALLBACK* _SIOopen)(void *pDsp);
|
|
||||||
typedef void (CALLBACK* _SIOclose)();
|
|
||||||
typedef void (CALLBACK* _SIOshutdown)();
|
|
||||||
typedef u8 (CALLBACK* _SIOstartPoll)(u8 value);
|
|
||||||
typedef u8 (CALLBACK* _SIOpoll)(u8 value);
|
|
||||||
typedef u32 (CALLBACK* _SIOquery)();
|
|
||||||
|
|
||||||
typedef void (CALLBACK* _SIOconfigure)();
|
|
||||||
typedef s32 (CALLBACK* _SIOtest)();
|
|
||||||
typedef void (CALLBACK* _SIOabout)();
|
|
||||||
|
|
||||||
// SPU2
|
|
||||||
typedef s32 (CALLBACK* _SPU2init)();
|
|
||||||
typedef s32 (CALLBACK* _SPU2open)(void *pDsp);
|
|
||||||
typedef void (CALLBACK* _SPU2close)();
|
|
||||||
typedef void (CALLBACK* _SPU2shutdown)();
|
|
||||||
typedef void (CALLBACK* _SPU2write)(u32 mem, u16 value);
|
|
||||||
typedef u16 (CALLBACK* _SPU2read)(u32 mem);
|
|
||||||
typedef void (CALLBACK* _SPU2readDMA4Mem)(u16 *pMem, int size);
|
|
||||||
typedef void (CALLBACK* _SPU2writeDMA4Mem)(u16 *pMem, int size);
|
|
||||||
typedef void (CALLBACK* _SPU2interruptDMA4)();
|
|
||||||
typedef void (CALLBACK* _SPU2readDMA7Mem)(u16 *pMem, int size);
|
|
||||||
typedef void (CALLBACK* _SPU2writeDMA7Mem)(u16 *pMem, int size);
|
|
||||||
typedef void (CALLBACK* _SPU2interruptDMA7)();
|
|
||||||
typedef void (CALLBACK* _SPU2irqCallback)(void (*callback)());
|
|
||||||
|
|
||||||
typedef void (CALLBACK* _SPU2async)(u32 cycles);
|
|
||||||
typedef s32 (CALLBACK* _SPU2freeze)(int mode, freezeData *data);
|
|
||||||
typedef void (CALLBACK* _SPU2configure)();
|
|
||||||
typedef s32 (CALLBACK* _SPU2test)();
|
|
||||||
typedef void (CALLBACK* _SPU2about)();
|
|
||||||
|
|
||||||
// CDVD
|
|
||||||
typedef s32 (CALLBACK* _CDVDinit)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDopen)();
|
|
||||||
typedef void (CALLBACK* _CDVDclose)();
|
|
||||||
typedef void (CALLBACK* _CDVDshutdown)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDreadTrack)(u32 lsn, int mode);
|
|
||||||
typedef u8* (CALLBACK* _CDVDgetBuffer)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq);
|
|
||||||
typedef s32 (CALLBACK* _CDVDgetTN)(cdvdTN *Buffer);
|
|
||||||
typedef s32 (CALLBACK* _CDVDgetTD)(u8 Track, cdvdTD *Buffer);
|
|
||||||
typedef s32 (CALLBACK* _CDVDgetTOC)(void* toc);
|
|
||||||
typedef s32 (CALLBACK* _CDVDgetDiskType)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDgetTrayStatus)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDctrlTrayOpen)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDctrlTrayClose)();
|
|
||||||
|
|
||||||
typedef void (CALLBACK* _CDVDconfigure)();
|
|
||||||
typedef s32 (CALLBACK* _CDVDtest)();
|
|
||||||
typedef void (CALLBACK* _CDVDabout)();
|
|
||||||
typedef void (CALLBACK* _CDVDnewDiskCB)(void (*callback)());
|
|
||||||
|
|
||||||
// DEV9
|
|
||||||
typedef s32 (CALLBACK* _DEV9init)();
|
|
||||||
typedef s32 (CALLBACK* _DEV9open)(void *pDsp);
|
|
||||||
typedef void (CALLBACK* _DEV9close)();
|
|
||||||
typedef void (CALLBACK* _DEV9shutdown)();
|
|
||||||
typedef u8 (CALLBACK* _DEV9read8)(u32 mem);
|
|
||||||
typedef u16 (CALLBACK* _DEV9read16)(u32 mem);
|
|
||||||
typedef u32 (CALLBACK* _DEV9read32)(u32 mem);
|
|
||||||
typedef void (CALLBACK* _DEV9write8)(u32 mem, u8 value);
|
|
||||||
typedef void (CALLBACK* _DEV9write16)(u32 mem, u16 value);
|
|
||||||
typedef void (CALLBACK* _DEV9write32)(u32 mem, u32 value);
|
|
||||||
typedef void (CALLBACK* _DEV9readDMA8Mem)(u32 *pMem, int size);
|
|
||||||
typedef void (CALLBACK* _DEV9writeDMA8Mem)(u32 *pMem, int size);
|
|
||||||
typedef void (CALLBACK* _DEV9irqCallback)(DEV9callback callback);
|
|
||||||
typedef DEV9handler (CALLBACK* _DEV9irqHandler)(void);
|
|
||||||
|
|
||||||
typedef s32 (CALLBACK* _DEV9freeze)(int mode, freezeData *data);
|
|
||||||
typedef void (CALLBACK* _DEV9configure)();
|
|
||||||
typedef s32 (CALLBACK* _DEV9test)();
|
|
||||||
typedef void (CALLBACK* _DEV9about)();
|
|
||||||
|
|
||||||
// USB
|
|
||||||
typedef s32 (CALLBACK* _USBinit)();
|
|
||||||
typedef s32 (CALLBACK* _USBopen)(void *pDsp);
|
|
||||||
typedef void (CALLBACK* _USBclose)();
|
|
||||||
typedef void (CALLBACK* _USBshutdown)();
|
|
||||||
typedef u8 (CALLBACK* _USBread8)(u32 mem);
|
|
||||||
typedef u16 (CALLBACK* _USBread16)(u32 mem);
|
|
||||||
typedef u32 (CALLBACK* _USBread32)(u32 mem);
|
|
||||||
typedef void (CALLBACK* _USBwrite8)(u32 mem, u8 value);
|
|
||||||
typedef void (CALLBACK* _USBwrite16)(u32 mem, u16 value);
|
|
||||||
typedef void (CALLBACK* _USBwrite32)(u32 mem, u32 value);
|
|
||||||
typedef void (CALLBACK* _USBirqCallback)(USBcallback callback);
|
|
||||||
typedef USBhandler (CALLBACK* _USBirqHandler)(void);
|
|
||||||
typedef void (CALLBACK* _USBsetRAM)(void *mem);
|
|
||||||
|
|
||||||
typedef s32 (CALLBACK* _USBfreeze)(int mode, freezeData *data);
|
|
||||||
typedef void (CALLBACK* _USBconfigure)();
|
|
||||||
typedef s32 (CALLBACK* _USBtest)();
|
|
||||||
typedef void (CALLBACK* _USBabout)();
|
|
||||||
|
|
||||||
//FW
|
|
||||||
typedef s32 (CALLBACK* _FWinit)();
|
|
||||||
typedef s32 (CALLBACK* _FWopen)(void *pDsp);
|
|
||||||
typedef void (CALLBACK* _FWclose)();
|
|
||||||
typedef void (CALLBACK* _FWshutdown)();
|
|
||||||
typedef u32 (CALLBACK* _FWread32)(u32 mem);
|
|
||||||
typedef void (CALLBACK* _FWwrite32)(u32 mem, u32 value);
|
|
||||||
typedef void (CALLBACK* _FWirqCallback)(void (*callback)());
|
|
||||||
|
|
||||||
typedef s32 (CALLBACK* _FWfreeze)(int mode, freezeData *data);
|
|
||||||
typedef void (CALLBACK* _FWconfigure)();
|
|
||||||
typedef s32 (CALLBACK* _FWtest)();
|
|
||||||
typedef void (CALLBACK* _FWabout)();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PLUGINfuncs
|
|
||||||
|
|
||||||
// GS
|
|
||||||
_GSinit GSinit;
|
|
||||||
_GSopen GSopen;
|
|
||||||
_GSclose GSclose;
|
|
||||||
_GSshutdown GSshutdown;
|
|
||||||
_GSvsync GSvsync;
|
|
||||||
_GSwrite8 GSwrite8;
|
|
||||||
_GSwrite16 GSwrite16;
|
|
||||||
_GSwrite32 GSwrite32;
|
|
||||||
_GSwrite64 GSwrite64;
|
|
||||||
_GSread8 GSread8;
|
|
||||||
_GSread16 GSread16;
|
|
||||||
_GSread32 GSread32;
|
|
||||||
_GSread64 GSread64;
|
|
||||||
_GSgifTransfer1 GSgifTransfer1;
|
|
||||||
_GSgifTransfer2 GSgifTransfer2;
|
|
||||||
_GSgifTransfer3 GSgifTransfer3;
|
|
||||||
_GSreadFIFO GSreadFIFO;
|
|
||||||
|
|
||||||
_GSkeyEvent GSkeyEvent;
|
|
||||||
_GSmakeSnapshot GSmakeSnapshot;
|
|
||||||
_GSirqCallback GSirqCallback;
|
|
||||||
_GSprintf GSprintf;
|
|
||||||
_GSsetCSR GSsetCSR;
|
|
||||||
_GSgetDriverInfo GSgetDriverInfo;
|
|
||||||
#ifdef __WIN32__
|
|
||||||
_GSsetWindowInfo GSsetWindowInfo;
|
|
||||||
#endif
|
|
||||||
_GSfreeze GSfreeze;
|
|
||||||
_GSconfigure GSconfigure;
|
|
||||||
_GStest GStest;
|
|
||||||
_GSabout GSabout;
|
|
||||||
|
|
||||||
// PAD1
|
|
||||||
_PADinit PAD1init;
|
|
||||||
_PADopen PAD1open;
|
|
||||||
_PADclose PAD1close;
|
|
||||||
_PADshutdown PAD1shutdown;
|
|
||||||
_PADkeyEvent PAD1keyEvent;
|
|
||||||
_PADstartPoll PAD1startPoll;
|
|
||||||
_PADpoll PAD1poll;
|
|
||||||
_PADquery PAD1query;
|
|
||||||
|
|
||||||
_PADgsDriverInfo PAD1gsDriverInfo;
|
|
||||||
_PADconfigure PAD1configure;
|
|
||||||
_PADtest PAD1test;
|
|
||||||
_PADabout PAD1about;
|
|
||||||
|
|
||||||
// PAD2
|
|
||||||
_PADinit PAD2init;
|
|
||||||
_PADopen PAD2open;
|
|
||||||
_PADclose PAD2close;
|
|
||||||
_PADshutdown PAD2shutdown;
|
|
||||||
_PADkeyEvent PAD2keyEvent;
|
|
||||||
_PADstartPoll PAD2startPoll;
|
|
||||||
_PADpoll PAD2poll;
|
|
||||||
_PADquery PAD2query;
|
|
||||||
|
|
||||||
_PADgsDriverInfo PAD2gsDriverInfo;
|
|
||||||
_PADconfigure PAD2configure;
|
|
||||||
_PADtest PAD2test;
|
|
||||||
_PADabout PAD2about;
|
|
||||||
|
|
||||||
// SIO[2]
|
|
||||||
_SIOinit SIOinit[2][9];
|
|
||||||
_SIOopen SIOopen[2][9];
|
|
||||||
_SIOclose SIOclose[2][9];
|
|
||||||
_SIOshutdown SIOshutdown[2][9];
|
|
||||||
_SIOstartPoll SIOstartPoll[2][9];
|
|
||||||
_SIOpoll SIOpoll[2][9];
|
|
||||||
_SIOquery SIOquery[2][9];
|
|
||||||
|
|
||||||
_SIOconfigure SIOconfigure[2][9];
|
|
||||||
_SIOtest SIOtest[2][9];
|
|
||||||
_SIOabout SIOabout[2][9];
|
|
||||||
|
|
||||||
// SPU2
|
|
||||||
_SPU2init SPU2init;
|
|
||||||
_SPU2open SPU2open;
|
|
||||||
_SPU2close SPU2close;
|
|
||||||
_SPU2shutdown SPU2shutdown;
|
|
||||||
_SPU2write SPU2write;
|
|
||||||
_SPU2read SPU2read;
|
|
||||||
_SPU2readDMA4Mem SPU2readDMA4Mem;
|
|
||||||
_SPU2writeDMA4Mem SPU2writeDMA4Mem;
|
|
||||||
_SPU2interruptDMA4 SPU2interruptDMA4;
|
|
||||||
_SPU2readDMA7Mem SPU2readDMA7Mem;
|
|
||||||
_SPU2writeDMA7Mem SPU2writeDMA7Mem;
|
|
||||||
_SPU2interruptDMA7 SPU2interruptDMA7;
|
|
||||||
_SPU2irqCallback SPU2irqCallback;
|
|
||||||
|
|
||||||
_SPU2async SPU2async;
|
|
||||||
_SPU2freeze SPU2freeze;
|
|
||||||
_SPU2configure SPU2configure;
|
|
||||||
_SPU2test SPU2test;
|
|
||||||
_SPU2about SPU2about;
|
|
||||||
|
|
||||||
// CDVD
|
|
||||||
_CDVDinit CDVDinit;
|
|
||||||
_CDVDopen CDVDopen;
|
|
||||||
_CDVDclose CDVDclose;
|
|
||||||
_CDVDshutdown CDVDshutdown;
|
|
||||||
_CDVDreadTrack CDVDreadTrack;
|
|
||||||
_CDVDgetBuffer CDVDgetBuffer;
|
|
||||||
_CDVDreadSubQ CDVDreadSubQ;
|
|
||||||
_CDVDgetTN CDVDgetTN;
|
|
||||||
_CDVDgetTD CDVDgetTD;
|
|
||||||
_CDVDgetTOC CDVDgetTOC;
|
|
||||||
_CDVDgetDiskType CDVDgetDiskType;
|
|
||||||
_CDVDgetTrayStatus CDVDgetTrayStatus;
|
|
||||||
_CDVDctrlTrayOpen CDVDctrlTrayOpen;
|
|
||||||
_CDVDctrlTrayClose CDVDctrlTrayClose;
|
|
||||||
|
|
||||||
_CDVDconfigure CDVDconfigure;
|
|
||||||
_CDVDtest CDVDtest;
|
|
||||||
_CDVDabout CDVDabout;
|
|
||||||
_CDVDnewDiskCB CDVDnewDiskCB;
|
|
||||||
|
|
||||||
// DEV9
|
|
||||||
_DEV9init DEV9init;
|
|
||||||
_DEV9open DEV9open;
|
|
||||||
_DEV9close DEV9close;
|
|
||||||
_DEV9shutdown DEV9shutdown;
|
|
||||||
_DEV9read8 DEV9read8;
|
|
||||||
_DEV9read16 DEV9read16;
|
|
||||||
_DEV9read32 DEV9read32;
|
|
||||||
_DEV9write8 DEV9write8;
|
|
||||||
_DEV9write16 DEV9write16;
|
|
||||||
_DEV9write32 DEV9write32;
|
|
||||||
_DEV9readDMA8Mem DEV9readDMA8Mem;
|
|
||||||
_DEV9writeDMA8Mem DEV9writeDMA8Mem;
|
|
||||||
_DEV9irqCallback DEV9irqCallback;
|
|
||||||
_DEV9irqHandler DEV9irqHandler;
|
|
||||||
|
|
||||||
_DEV9configure DEV9configure;
|
|
||||||
_DEV9freeze DEV9freeze;
|
|
||||||
_DEV9test DEV9test;
|
|
||||||
_DEV9about DEV9about;
|
|
||||||
|
|
||||||
// USB
|
|
||||||
_USBinit USBinit;
|
|
||||||
_USBopen USBopen;
|
|
||||||
_USBclose USBclose;
|
|
||||||
_USBshutdown USBshutdown;
|
|
||||||
_USBread8 USBread8;
|
|
||||||
_USBread16 USBread16;
|
|
||||||
_USBread32 USBread32;
|
|
||||||
_USBwrite8 USBwrite8;
|
|
||||||
_USBwrite16 USBwrite16;
|
|
||||||
_USBwrite32 USBwrite32;
|
|
||||||
_USBirqCallback USBirqCallback;
|
|
||||||
_USBirqHandler USBirqHandler;
|
|
||||||
_USBsetRAM USBsetRAM;
|
|
||||||
|
|
||||||
_USBconfigure USBconfigure;
|
|
||||||
_USBfreeze USBfreeze;
|
|
||||||
_USBtest USBtest;
|
|
||||||
_USBabout USBabout;
|
|
||||||
|
|
||||||
// FW
|
|
||||||
_FWinit FWinit;
|
|
||||||
_FWopen FWopen;
|
|
||||||
_FWclose FWclose;
|
|
||||||
_FWshutdown FWshutdown;
|
|
||||||
_FWread32 FWread32;
|
|
||||||
_FWwrite32 FWwrite32;
|
|
||||||
_FWirqCallback FWirqCallback;
|
|
||||||
|
|
||||||
_FWconfigure FWconfigure;
|
|
||||||
_FWfreeze FWfreeze;
|
|
||||||
_FWtest FWtest;
|
|
||||||
_FWabout FWabout;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __PS2EDEFS_H__ */
|
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef __PS2ETYPES_H__
|
|
||||||
#define __PS2ETYPES_H__
|
|
||||||
|
|
||||||
// Basic types
|
|
||||||
#if defined(__MSCW32__)
|
|
||||||
|
|
||||||
typedef __int8 s8;
|
|
||||||
typedef __int16 s16;
|
|
||||||
typedef __int32 s32;
|
|
||||||
typedef __int64 s64;
|
|
||||||
|
|
||||||
typedef unsigned __int8 u8;
|
|
||||||
typedef unsigned __int16 u16;
|
|
||||||
typedef unsigned __int32 u32;
|
|
||||||
typedef unsigned __int64 u64;
|
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
typedef u64 uptr;
|
|
||||||
#else
|
|
||||||
typedef u32 uptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__linux__) || defined(__MINGW32__)
|
|
||||||
|
|
||||||
typedef char s8;
|
|
||||||
typedef short s16;
|
|
||||||
typedef int s32;
|
|
||||||
typedef long long s64;
|
|
||||||
|
|
||||||
typedef unsigned char u8;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
typedef unsigned long long u64;
|
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
typedef u64 uptr;
|
|
||||||
#else
|
|
||||||
typedef u32 uptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __PS2ETYPES_H__ */
|
|
|
@ -1,37 +0,0 @@
|
||||||
========================================================================
|
|
||||||
DYNAMIC LINK LIBRARY : cdrPeops
|
|
||||||
========================================================================
|
|
||||||
|
|
||||||
|
|
||||||
AppWizard has created this cdrPeops DLL for you.
|
|
||||||
|
|
||||||
This file contains a summary of what you will find in each of the files that
|
|
||||||
make up your cdrPeops application.
|
|
||||||
|
|
||||||
cdrPeops.dsp
|
|
||||||
This file (the project file) contains information at the project level and
|
|
||||||
is used to build a single project or subproject. Other users can share the
|
|
||||||
project (.dsp) file, but they should export the makefiles locally.
|
|
||||||
|
|
||||||
cdrPeops.cpp
|
|
||||||
This is the main DLL source file.
|
|
||||||
|
|
||||||
cdrPeops.h
|
|
||||||
This file contains your DLL exports.
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
Other standard files:
|
|
||||||
|
|
||||||
StdAfx.h, StdAfx.cpp
|
|
||||||
These files are used to build a precompiled header (PCH) file
|
|
||||||
named cdrPeops.pch and a precompiled types file named StdAfx.obj.
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
Other notes:
|
|
||||||
|
|
||||||
AppWizard uses "TODO:" to indicate parts of the source code you
|
|
||||||
should add to or customize.
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +0,0 @@
|
||||||
// stdafx.cpp : source file that includes just the standard includes
|
|
||||||
// cdvdPeops.pch will be the pre-compiled header
|
|
||||||
// stdafx.obj will contain the pre-compiled type information
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
// reference any additional headers you need in STDAFX.H
|
|
||||||
// and not in this file
|
|
|
@ -1,82 +0,0 @@
|
||||||
// stdafx.h : include file for standard system include files,
|
|
||||||
// or project specific include files that are used frequently, but
|
|
||||||
// are changed infrequently
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(AFX_STDAFX_H__A412EBA3_CBB9_11D6_A315_008048C61B72__INCLUDED_)
|
|
||||||
#define AFX_STDAFX_H__A412EBA3_CBB9_11D6_A315_008048C61B72__INCLUDED_
|
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
|
||||||
#pragma once
|
|
||||||
#endif // _MSC_VER > 1000
|
|
||||||
|
|
||||||
#ifdef _GCC
|
|
||||||
#define EXPORT_GCC __declspec (dllexport)
|
|
||||||
#else
|
|
||||||
#define EXPORT_GCC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Insert your headers here
|
|
||||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <process.h>
|
|
||||||
#include <commdlg.h>
|
|
||||||
#include <windowsx.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
// special setup for MinGW/Dev-C++ ################### //
|
|
||||||
// (I don't want to change PS2Edefs.h/PS2Etypes.h)
|
|
||||||
|
|
||||||
#undef __WIN32__
|
|
||||||
|
|
||||||
typedef char s8;
|
|
||||||
typedef short s16;
|
|
||||||
typedef long s32;
|
|
||||||
#ifdef _GCC
|
|
||||||
typedef long long s64;
|
|
||||||
#else
|
|
||||||
typedef __int64 s64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned char u8;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef unsigned long u32;
|
|
||||||
#ifdef _GCC
|
|
||||||
typedef unsigned long long u64;
|
|
||||||
#else
|
|
||||||
typedef unsigned __int64 u64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "PS2Edefs.h"
|
|
||||||
|
|
||||||
#define __WIN32__
|
|
||||||
|
|
||||||
// ################################################### //
|
|
||||||
|
|
||||||
|
|
||||||
#include "wnaspi32.h"
|
|
||||||
#include "scsidefs.h"
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
#include "cdda.h"
|
|
||||||
#include "cdr.h"
|
|
||||||
#include "cfg.h"
|
|
||||||
#include "generic.h"
|
|
||||||
#include "ioctrl.h"
|
|
||||||
#include "ppf.h"
|
|
||||||
#include "read.h"
|
|
||||||
#include "scsi.h"
|
|
||||||
#include "sub.h"
|
|
||||||
#include "toc.h"
|
|
||||||
|
|
||||||
//#define DBGOUT
|
|
||||||
|
|
||||||
//{{AFX_INSERT_LOCATION}}
|
|
||||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
|
||||||
|
|
||||||
#endif // !defined(AFX_STDAFX_H__A412EBA3_CBB9_11D6_A315_008048C61B72__INCLUDED_)
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
curdir=`pwd`
|
|
||||||
|
|
||||||
echo ------------------
|
|
||||||
echo Building CDVDpeops
|
|
||||||
echo ------------------
|
|
||||||
|
|
||||||
cd ${curdir}/src/Linux
|
|
||||||
make $@
|
|
||||||
|
|
||||||
# copy the files
|
|
||||||
if [ -s cfgCDVDpeops ] && [ -s libCDVDpeops.so ]
|
|
||||||
then
|
|
||||||
cp cfgCDVDpeops libCDVDpeops.so ${PCSX2PLUGINS}
|
|
||||||
fi
|
|
|
@ -1,80 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cdda.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_CDDA
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// starts/stops audio playing (addr==0 -> stop)
|
|
||||||
// note: no cdda support in PS2 plugins yet
|
|
||||||
|
|
||||||
BOOL DoCDDAPlay(unsigned long addr)
|
|
||||||
{
|
|
||||||
DWORD dw;
|
|
||||||
|
|
||||||
LockGenCDAccess();
|
|
||||||
|
|
||||||
if(addr) dw=PlaySCSIAudio(addr,lMaxAddr-addr); // start playing (til end of cd)
|
|
||||||
// mmm... this stop doesn't work right
|
|
||||||
// else dw=PlayFunc(0,1);
|
|
||||||
else // funny stop... but seems to work
|
|
||||||
{
|
|
||||||
unsigned char cdb[3000];
|
|
||||||
FRAMEBUF * f=(FRAMEBUF *)cdb;
|
|
||||||
|
|
||||||
f->dwFrame = 16; // -> use an existing address (16 will ever exist on ps2 cds/dvds)
|
|
||||||
f->dwFrameCnt = 1;
|
|
||||||
f->dwBufLen = 2352;
|
|
||||||
|
|
||||||
dw=pReadFunc(1,f); // -> do a simply sync read... seems to stop all audio playing
|
|
||||||
}
|
|
||||||
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
if(dw!=SS_COMP) return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// get curr playing pos
|
|
||||||
|
|
||||||
unsigned char * GetCDDAPlayPosition(void)
|
|
||||||
{
|
|
||||||
unsigned char * pos;
|
|
||||||
|
|
||||||
LockGenCDAccess();
|
|
||||||
|
|
||||||
pos=GetSCSIAudioSub(); // get the pos (scsi command)
|
|
||||||
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,28 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cdda.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
BOOL DoCDDAPlay(unsigned long addr);
|
|
||||||
unsigned char * GetCDDAPlayPosition(void);
|
|
|
@ -1,27 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cdr.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
// nothing yet
|
|
|
@ -1,89 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cdvdPeops.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
// cdrPeops.cpp : Defines the entry point for the DLL application.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "cdvdPeops.h"
|
|
||||||
#define _IN_PEOPS
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HINSTANCE hInst=0;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// get selected interface mode from registry: needed,
|
|
||||||
// if user has w2k and aspi available, so the plugin
|
|
||||||
// can know, what he wants to use
|
|
||||||
|
|
||||||
int iGetUserInterfaceMode(void)
|
|
||||||
{
|
|
||||||
HKEY myKey;DWORD temp;DWORD type;DWORD size;
|
|
||||||
int iRet=0;
|
|
||||||
|
|
||||||
if(RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\PS2Eplugin\\CDVD\\CDVDPeops",0,KEY_ALL_ACCESS,&myKey)==ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"InterfaceMode",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iRet=(int)temp;
|
|
||||||
RegCloseKey(myKey);
|
|
||||||
}
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// dll entry point
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HANDLE hModule,
|
|
||||||
DWORD ul_reason_for_call,
|
|
||||||
LPVOID lpReserved)
|
|
||||||
{
|
|
||||||
hInst=(HINSTANCE)hModule;
|
|
||||||
|
|
||||||
switch (ul_reason_for_call)
|
|
||||||
{//--------------------------------------------------//
|
|
||||||
case DLL_PROCESS_ATTACH:
|
|
||||||
iInterfaceMode=iGetUserInterfaceMode(); // get interface on startup
|
|
||||||
OpenGenInterface(); // open interface (can be changed in the config window)
|
|
||||||
break;
|
|
||||||
//--------------------------------------------------//
|
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
CloseGenInterface(); // close interface
|
|
||||||
break;
|
|
||||||
//--------------------------------------------------//
|
|
||||||
case DLL_THREAD_ATTACH:
|
|
||||||
break;
|
|
||||||
//--------------------------------------------------//
|
|
||||||
case DLL_THREAD_DETACH:
|
|
||||||
break;
|
|
||||||
//--------------------------------------------------//
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,30 +0,0 @@
|
||||||
; cdvdPeops.def : Declares the module parameters for the DLL.
|
|
||||||
|
|
||||||
LIBRARY "cdvdPeops"
|
|
||||||
|
|
||||||
EXPORTS
|
|
||||||
; Explicit exports can go here
|
|
||||||
|
|
||||||
PS2EgetLibType @2
|
|
||||||
PS2EgetLibName @3
|
|
||||||
PS2EgetLibVersion2 @4
|
|
||||||
CDVDinit @5
|
|
||||||
CDVDshutdown @6
|
|
||||||
CDVDopen @7
|
|
||||||
CDVDclose @8
|
|
||||||
CDVDconfigure @9
|
|
||||||
CDVDabout @10
|
|
||||||
CDVDtest @11
|
|
||||||
CDVDgetTN @12
|
|
||||||
CDVDgetTD @13
|
|
||||||
CDVDreadTrack @14
|
|
||||||
CDVDgetBuffer @15
|
|
||||||
CDVDgetDiskType @16
|
|
||||||
CDVDgetTrayStatus @17
|
|
||||||
CDVDreadSubQ @18
|
|
||||||
CDVDgetTOC @19
|
|
||||||
CDVDctrlTrayOpen @20
|
|
||||||
CDVDctrlTrayClose @21
|
|
||||||
; PS2EgetCpuPlatform @18
|
|
||||||
|
|
||||||
|
|
|
@ -1,418 +0,0 @@
|
||||||
[Project]
|
|
||||||
FileName=cdvdPeops.dev
|
|
||||||
Name=cdvdPeops
|
|
||||||
Ver=1
|
|
||||||
IsCpp=1
|
|
||||||
Type=3
|
|
||||||
Compiler=-D__GNUWIN32__ -mcpu=pentium -D_M_IX86=500 -W -DWIN32 -DNDEBUG -D_WINDOWS -D_GCC_@@_
|
|
||||||
CppCompiler=-D__GNUWIN32__ -mcpu=pentium -D_M_IX86=500 -W -DWIN32 -DNDEBUG -D_WINDOWS -D_GCC_@@_
|
|
||||||
Includes=d:\vs\vc98\MFC\include
|
|
||||||
Linker=-lkernel32 -luser32 -ladvapi32 -lcomdlg32 --add-stdcall-alias_@@_
|
|
||||||
Libs=
|
|
||||||
UnitCount=37
|
|
||||||
Folders="Documentation files","Header Files","Resource Files","Source Files"
|
|
||||||
ObjFiles=
|
|
||||||
PrivateResource=cdvdPeops_private.rc
|
|
||||||
ResourceIncludes=
|
|
||||||
MakeIncludes=
|
|
||||||
Icon=
|
|
||||||
ExeOutput=..\..\..\emus\pcsx2_0.6\plugins
|
|
||||||
ObjectOutput=Release
|
|
||||||
OverrideOutput=1
|
|
||||||
OverrideOutputName=cdvdPeops.dll
|
|
||||||
HostApplication=
|
|
||||||
CommandLine=
|
|
||||||
UseCustomMakefile=0
|
|
||||||
CustomMakefile=OwnMakefile.win
|
|
||||||
IncludeVersionInfo=0
|
|
||||||
SupportXPThemes=0
|
|
||||||
CompilerSet=0
|
|
||||||
CompilerSettings=0000000001001000000000
|
|
||||||
|
|
||||||
[Unit1]
|
|
||||||
FileName=cdr.c
|
|
||||||
CompileCpp=0
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit2]
|
|
||||||
FileName=cdvdPeops.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit3]
|
|
||||||
FileName=cdvdPeops.def
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=0
|
|
||||||
CompileCpp=0
|
|
||||||
Link=0
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit4]
|
|
||||||
FileName=cfg.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit5]
|
|
||||||
FileName=generic.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit6]
|
|
||||||
FileName=ioctrl.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit7]
|
|
||||||
FileName=ppf.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit8]
|
|
||||||
FileName=read.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit9]
|
|
||||||
FileName=scsi.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit10]
|
|
||||||
FileName=StdAfx.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit11]
|
|
||||||
FileName=sub.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit12]
|
|
||||||
FileName=toc.c
|
|
||||||
Folder="Source Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit13]
|
|
||||||
FileName=cdda.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit14]
|
|
||||||
FileName=cdr.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit15]
|
|
||||||
FileName=cdvdPeops.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit16]
|
|
||||||
FileName=cfg.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit17]
|
|
||||||
FileName=defines.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit18]
|
|
||||||
FileName=externals.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit19]
|
|
||||||
FileName=generic.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit20]
|
|
||||||
FileName=ioctrl.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit21]
|
|
||||||
FileName=ppf.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit22]
|
|
||||||
FileName=read.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit23]
|
|
||||||
FileName=resource.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit24]
|
|
||||||
FileName=scsi.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit25]
|
|
||||||
FileName=scsidefs.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit26]
|
|
||||||
FileName=StdAfx.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit27]
|
|
||||||
FileName=sub.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit28]
|
|
||||||
FileName=toc.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit29]
|
|
||||||
FileName=wnaspi32.h
|
|
||||||
Folder="Header Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit30]
|
|
||||||
FileName=cdvdPeops.rc
|
|
||||||
Folder="Resource Files"
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=1
|
|
||||||
Link=0
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit31]
|
|
||||||
FileName=changelog.txt
|
|
||||||
Folder="Documentation files"
|
|
||||||
Compile=0
|
|
||||||
CompileCpp=1
|
|
||||||
Link=0
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit32]
|
|
||||||
FileName=filemap.txt
|
|
||||||
Folder="Documentation files"
|
|
||||||
Compile=0
|
|
||||||
CompileCpp=0
|
|
||||||
Link=0
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit33]
|
|
||||||
FileName=license.txt
|
|
||||||
Folder="Documentation files"
|
|
||||||
Compile=0
|
|
||||||
CompileCpp=0
|
|
||||||
Link=0
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit34]
|
|
||||||
FileName=cdda.c
|
|
||||||
Folder=Source Files
|
|
||||||
Compile=1
|
|
||||||
CompileCpp=0
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=$(CC) -c cdda.c -o cdda.o $(CFLAGS)
|
|
||||||
|
|
||||||
[VersionInfo]
|
|
||||||
Major=0
|
|
||||||
Minor=1
|
|
||||||
Release=1
|
|
||||||
Build=1
|
|
||||||
LanguageID=1033
|
|
||||||
CharsetID=1252
|
|
||||||
CompanyName=
|
|
||||||
FileVersion=0.1
|
|
||||||
FileDescription=Developed using the Dev-C++ IDE
|
|
||||||
InternalName=
|
|
||||||
LegalCopyright=
|
|
||||||
LegalTrademarks=
|
|
||||||
OriginalFilename=cdvdPeops.exe
|
|
||||||
ProductName=cdvdPeops
|
|
||||||
ProductVersion=0.1
|
|
||||||
AutoIncBuildNr=0
|
|
||||||
|
|
||||||
[Unit35]
|
|
||||||
FileName=i386.asm
|
|
||||||
Folder=Source Files
|
|
||||||
Compile=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=1
|
|
||||||
BuildCmd=nasmw.exe -f win32 -D__WIN32__ -D__i386__ i386.asm -o release\i386.o
|
|
||||||
|
|
||||||
[Unit36]
|
|
||||||
FileName=PS2Edefs.h
|
|
||||||
CompileCpp=1
|
|
||||||
Folder=Header Files
|
|
||||||
Compile=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
||||||
[Unit37]
|
|
||||||
FileName=PS2Etypes.h
|
|
||||||
CompileCpp=1
|
|
||||||
Folder=Header Files
|
|
||||||
Compile=1
|
|
||||||
Link=1
|
|
||||||
Priority=1000
|
|
||||||
OverrideBuildCmd=0
|
|
||||||
BuildCmd=
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cdvdPeops.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Nov 12 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
|
@ -1,235 +0,0 @@
|
||||||
//Microsoft Developer Studio generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Neutral resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifndef _MAC
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 1,0,2,0
|
|
||||||
PRODUCTVERSION 1,0,2,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x2L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040704b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Comments", "\0"
|
|
||||||
VALUE "CompanyName", "Pete Bernert and the P.E.Op.S. team\0"
|
|
||||||
VALUE "FileDescription", "cdvdPeops\0"
|
|
||||||
VALUE "FileVersion", "1, 0, 2, 0\0"
|
|
||||||
VALUE "InternalName", "cdvdPeops\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright © 2003-2004\0"
|
|
||||||
VALUE "LegalTrademarks", "\0"
|
|
||||||
VALUE "OriginalFilename", "cdvdPeops.dll\0"
|
|
||||||
VALUE "PrivateBuild", "\0"
|
|
||||||
VALUE "ProductName", "cdvdPeops\0"
|
|
||||||
VALUE "ProductVersion", "1, 0, 2, 0\0"
|
|
||||||
VALUE "SpecialBuild", "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x407, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // !_MAC
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Dialog
|
|
||||||
//
|
|
||||||
|
|
||||||
IDD_CONFIG DIALOG DISCARDABLE 0, 0, 287, 239
|
|
||||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
|
||||||
CAPTION "Configure the P.E.Op.S. ASPI/IOCTL PS2 CDVD Driver..."
|
|
||||||
FONT 8, "MS Sans Serif"
|
|
||||||
BEGIN
|
|
||||||
COMBOBOX IDC_IMODE,63,6,199,52,CBS_DROPDOWNLIST | WS_VSCROLL |
|
|
||||||
WS_TABSTOP
|
|
||||||
COMBOBOX IDC_DRIVE,63,22,199,52,CBS_DROPDOWNLIST | WS_VSCROLL |
|
|
||||||
WS_TABSTOP
|
|
||||||
COMBOBOX IDC_CACHE,63,39,199,65,CBS_DROPDOWNLIST | WS_VSCROLL |
|
|
||||||
WS_TABSTOP
|
|
||||||
CONTROL "Use additional 4 MByte data cache",IDC_DATACACHE,"Button",
|
|
||||||
BS_AUTOCHECKBOX | WS_TABSTOP,63,55,156,11
|
|
||||||
CONTROL "Try to limit speed (not supported by all drives)",
|
|
||||||
IDC_SPEEDLIMIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,
|
|
||||||
76,156,11
|
|
||||||
COMBOBOX IDC_SPEED,204,75,33,93,CBS_DROPDOWNLIST | WS_VSCROLL |
|
|
||||||
WS_TABSTOP
|
|
||||||
CONTROL "Don't wait until drive is ready (needed by a few drives)",
|
|
||||||
IDC_NOWAIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,89,
|
|
||||||
198,11
|
|
||||||
CONTROL "Check tray state (not tested, you can leave that off)",
|
|
||||||
IDC_TRAYSTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,
|
|
||||||
102,186,11
|
|
||||||
CONTROL "Try again on reading error. Retry count (1-10):",
|
|
||||||
IDC_TRYAGAIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,
|
|
||||||
129,156,11
|
|
||||||
EDITTEXT IDC_RETRY,204,128,33,13,ES_AUTOHSCROLL
|
|
||||||
CONTROL "Show message box on reading error",IDC_SHOWREADERR,
|
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,142,156,11
|
|
||||||
CONTROL "Use PPF patch file:",IDC_USEPPF,"Button",
|
|
||||||
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,13,168,74,11
|
|
||||||
EDITTEXT IDC_PPFFILE,89,168,167,12,ES_AUTOHSCROLL | WS_DISABLED
|
|
||||||
PUSHBUTTON "...",IDC_CHOOSEFILE,259,168,13,12,WS_DISABLED
|
|
||||||
COMBOBOX IDC_SUBCHAN0,13,197,261,52,CBS_DROPDOWNLIST |
|
|
||||||
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
|
|
||||||
EDITTEXT IDC_SUBFILE,63,197,193,12,ES_AUTOHSCROLL | WS_DISABLED
|
|
||||||
PUSHBUTTON "...",IDC_CHOOSESUBF,259,197,13,12,WS_DISABLED
|
|
||||||
DEFPUSHBUTTON "OK",IDOK,63,221,50,14
|
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,175,221,50,14
|
|
||||||
RTEXT "Drive:",IDC_STATIC,37,24,21,11
|
|
||||||
RTEXT "Caching mode:",IDC_STATIC,9,41,49,11
|
|
||||||
GROUPBOX "Error handling",IDC_STATIC,6,119,275,38
|
|
||||||
GROUPBOX "PPF patches",IDC_STATIC,6,158,275,28
|
|
||||||
GROUPBOX "Misc",IDC_STATIC,6,66,275,52
|
|
||||||
RTEXT "Interface:",IDC_STATIC,15,8,43,11
|
|
||||||
GROUPBOX "Subchannel reading",IDC_STATIC,6,187,275,29
|
|
||||||
RTEXT "File:",IDC_SFSTATIC,26,198,30,11,SS_CENTERIMAGE
|
|
||||||
END
|
|
||||||
|
|
||||||
IDD_ABOUT DIALOGEX 0, 0, 238, 210
|
|
||||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
|
||||||
CAPTION "About the P.E.Op.S. ASPI/IOCTL PS2 CDVD Driver..."
|
|
||||||
FONT 8, "MS Sans Serif"
|
|
||||||
BEGIN
|
|
||||||
DEFPUSHBUTTON "OK",IDOK,98,188,44,14
|
|
||||||
RTEXT "Version :",IDC_STATIC,5,5,74,9
|
|
||||||
RTEXT "Release date :",IDC_STATIC,5,16,74,9
|
|
||||||
RTEXT "Coded by :",IDC_STATIC,5,27,74,9
|
|
||||||
RTEXT "Pete's EMail :",IDC_STATIC,5,40,74,9
|
|
||||||
RTEXT "Pete's homepage :",IDC_STATIC,5,51,74,9
|
|
||||||
LTEXT "1.2",IDC_STATIC,82,5,154,9
|
|
||||||
LTEXT "25.12.2004",IDC_STATIC,81,16,154,9
|
|
||||||
LTEXT "Pete Bernert and the P.E.Op.S. team",IDC_STATIC,81,27,
|
|
||||||
154,9
|
|
||||||
LTEXT "BlackDove@addcom.de",IDC_STATIC,81,39,154,9
|
|
||||||
LTEXT "http://www.pbernert.com",IDC_STATIC,81,51,154,9
|
|
||||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,9,100,218,81,
|
|
||||||
WS_EX_DLGMODALFRAME
|
|
||||||
RTEXT "Thanks to :",IDC_STATIC,16,109,38,9
|
|
||||||
LTEXT "the PCSX2 team - special thanx to shadow for kicking my ass",
|
|
||||||
IDC_STATIC,57,109,161,18
|
|
||||||
LTEXT "My girlfriend Heike... because everything I do wouldn't be the same without her",
|
|
||||||
IDC_STATIC,57,130,161,19
|
|
||||||
RTEXT "P.E.Op.S. homepage :",IDC_STATIC,5,80,74,9
|
|
||||||
LTEXT "https://sourceforge.net/projects/peops/",IDC_STATIC,81,
|
|
||||||
80,154,9
|
|
||||||
RTEXT "linuzappz :",IDC_STATIC,10,63,69,10
|
|
||||||
LTEXT "http://www.pcsx.net",IDC_STATIC,81,63,142,10
|
|
||||||
END
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// DESIGNINFO
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
GUIDELINES DESIGNINFO DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
IDD_CONFIG, DIALOG
|
|
||||||
BEGIN
|
|
||||||
LEFTMARGIN, 7
|
|
||||||
RIGHTMARGIN, 280
|
|
||||||
TOPMARGIN, 7
|
|
||||||
BOTTOMMARGIN, 232
|
|
||||||
END
|
|
||||||
|
|
||||||
IDD_ABOUT, DIALOG
|
|
||||||
BEGIN
|
|
||||||
LEFTMARGIN, 7
|
|
||||||
RIGHTMARGIN, 231
|
|
||||||
TOPMARGIN, 7
|
|
||||||
BOTTOMMARGIN, 203
|
|
||||||
END
|
|
||||||
END
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // Neutral resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// German (Germany) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // German (Germany) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdvdPeops", "cdvdPeops.vcproj", "{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
|
||||||
Debug = Debug
|
|
||||||
Release = Release
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfiguration) = postSolution
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Debug.ActiveCfg = Debug|Win32
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Debug.Build.0 = Debug|Win32
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Release.ActiveCfg = Release|Win32
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Release.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,19 +0,0 @@
|
||||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
|
||||||
# Visual Studio 2005
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdvdPeops", "cdvdPeops_2005.vcproj", "{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{74689B0D-A4E7-4D0E-A2D8-8A30EA455BC6}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,23 +0,0 @@
|
||||||
// THIS FILE WILL BE OVERWRITTEN BY DEV-C++!
|
|
||||||
// DO NOT EDIT!
|
|
||||||
|
|
||||||
#ifndef CDVDPEOPS_PRIVATE_H
|
|
||||||
#define CDVDPEOPS_PRIVATE_H
|
|
||||||
|
|
||||||
// VERSION DEFINITIONS
|
|
||||||
#define VER_STRING "0.1.1.1"
|
|
||||||
#define VER_MAJOR 0
|
|
||||||
#define VER_MINOR 1
|
|
||||||
#define VER_RELEASE 1
|
|
||||||
#define VER_BUILD 1
|
|
||||||
#define COMPANY_NAME ""
|
|
||||||
#define FILE_VERSION "0.1"
|
|
||||||
#define FILE_DESCRIPTION "Developed using the Dev-C++ IDE"
|
|
||||||
#define INTERNAL_NAME ""
|
|
||||||
#define LEGAL_COPYRIGHT ""
|
|
||||||
#define LEGAL_TRADEMARKS ""
|
|
||||||
#define ORIGINAL_FILENAME "cdvdPeops.exe"
|
|
||||||
#define PRODUCT_NAME "cdvdPeops"
|
|
||||||
#define PRODUCT_VERSION "0.1"
|
|
||||||
|
|
||||||
#endif //CDVDPEOPS_PRIVATE_H
|
|
|
@ -1,4 +0,0 @@
|
||||||
// THIS FILE WILL BE OVERWRITTEN BY DEV-C++!
|
|
||||||
// DO NOT EDIT!
|
|
||||||
|
|
||||||
#include "cdvdPeops.rc"
|
|
|
@ -1,47 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cfg.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void ReadConfig(void);
|
|
||||||
void WriteConfig(void);
|
|
||||||
void OnChooseFile(HWND hW,int iFType);
|
|
||||||
void EnumDrives(HWND hW);
|
|
||||||
void GetCDRInfos(HWND hW,int * iA, int * iT,int * iL);
|
|
||||||
void OnIMode(HWND hW);
|
|
||||||
void OnCache(HWND hW);
|
|
||||||
void ShowSubFileStuff(HWND hW);
|
|
||||||
BOOL OnInitCDRDialog(HWND hW);
|
|
||||||
void OnCDRAuto(HWND hW);
|
|
||||||
void ShowProgress(HWND hW,long lact,long lmin,long lmax);
|
|
||||||
void WriteDiffSub(FILE * xfile,int i,unsigned char * lpX,int iM,BOOL b3Min);
|
|
||||||
BOOL OnCreateSubFileEx(HWND hW,HWND hWX,BOOL b3Min);
|
|
||||||
BOOL OnCreateSubEx(HWND hW,HWND hWX,int iM,BOOL b3Min);
|
|
||||||
void StartSubReading(HWND hW,HWND hWX);
|
|
||||||
BOOL CALLBACK SubDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
void OnCreateSub(HWND hW);
|
|
||||||
void OnCDROK(HWND hW);
|
|
||||||
void OnCDRCancel(HWND hW);
|
|
||||||
BOOL CALLBACK CDRDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
@ -1,19 +0,0 @@
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
Version 1.2
|
|
||||||
-----------
|
|
||||||
- Pete: added an hack in CDVDgetTD for big dvds
|
|
||||||
- Pete: fixed a track size calculation bug
|
|
||||||
|
|
||||||
|
|
||||||
Version 1.1
|
|
||||||
-----------
|
|
||||||
- Pete: added dvd support for Plextor PX-708A
|
|
||||||
|
|
||||||
Version 1.0
|
|
||||||
-----------
|
|
||||||
- First release
|
|
||||||
Pete Bernert: ported the P.E.Op.S. PSX cdr plugin to PS2 needs
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
|
@ -1,212 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
defines.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// general buffer for reading several frames
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
typedef struct _FRAMEBUF
|
|
||||||
{
|
|
||||||
DWORD dwFrame;
|
|
||||||
DWORD dwFrameCnt;
|
|
||||||
DWORD dwBufLen;
|
|
||||||
unsigned char BufData[1024*1024];
|
|
||||||
} FRAMEBUF;
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
// raw ioctl structs:
|
|
||||||
|
|
||||||
typedef enum _TRACK_MODE_TYPE
|
|
||||||
{
|
|
||||||
YellowMode2,
|
|
||||||
XAForm2,
|
|
||||||
CDDA
|
|
||||||
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
|
|
||||||
|
|
||||||
typedef struct _RAW_READ_INFO
|
|
||||||
{
|
|
||||||
LARGE_INTEGER DiskOffset;
|
|
||||||
ULONG SectorCount;
|
|
||||||
TRACK_MODE_TYPE TrackMode;
|
|
||||||
} RAW_READ_INFO, *PRAW_READ_INFO;
|
|
||||||
|
|
||||||
// sub cache:
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
long addr;
|
|
||||||
void * pNext;
|
|
||||||
unsigned char subq[10];
|
|
||||||
} SUB_DATA;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
long addr;
|
|
||||||
void * pNext;
|
|
||||||
} SUB_CACHE;
|
|
||||||
|
|
||||||
// ppf cache:
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
long addr;
|
|
||||||
void * pNext;
|
|
||||||
long pos;
|
|
||||||
long anz;
|
|
||||||
// memdata
|
|
||||||
} PPF_DATA;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
long addr;
|
|
||||||
void * pNext;
|
|
||||||
} PPF_CACHE;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define MODE_BE_1 1
|
|
||||||
#define MODE_BE_2 2
|
|
||||||
#define MODE_28_1 3
|
|
||||||
#define MODE_28_2 4
|
|
||||||
#define MODE_28_2048 5
|
|
||||||
#define MODE_28_2048_Ex 6
|
|
||||||
|
|
||||||
#define itob(i) ((i)/10*16 + (i)%10)
|
|
||||||
#define btoi(b) ((b)/16*10 + (b)%16)
|
|
||||||
#define itod(i) ((((i)/10)<<4) + ((i)%10))
|
|
||||||
#define dtoi(b) ((((b)>>4)&0xf)*10 + (((b)&0xf)%10))
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void addr2time(unsigned long addr, unsigned char *time);
|
|
||||||
void addr2timeB(unsigned long addr, unsigned char *time);
|
|
||||||
unsigned long time2addr(unsigned char *time);
|
|
||||||
unsigned long time2addrB(unsigned char *time);
|
|
||||||
#ifdef _GCC
|
|
||||||
#define reOrder i386_reOrder
|
|
||||||
#endif
|
|
||||||
unsigned long reOrder(unsigned long value);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// debug helper
|
|
||||||
|
|
||||||
#ifndef _IN_CDR
|
|
||||||
#ifdef DBGOUT
|
|
||||||
void auxprintf (LPCTSTR pFormat, ...);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef DWORD (*READFUNC)(BOOL bWait,FRAMEBUF * f);
|
|
||||||
typedef DWORD (*DEINITFUNC)(void);
|
|
||||||
typedef BOOL (*READTRACKFUNC)(unsigned long addr);
|
|
||||||
typedef void (*GETPTRFUNC)(void);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define WAITFOREVER 0xFFFFFFFF
|
|
||||||
#define WAITSUB 10000
|
|
||||||
#define FRAMEBUFEXTRA 12
|
|
||||||
#define CDSECTOR 2352
|
|
||||||
#define MAXCACHEBLOCK 26
|
|
||||||
#define MAXCDBUFFER (((MAXCACHEBLOCK+1)*(CDSECTOR+16))+240)
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/* some structs from libcdvd by Hiryu & Sjeep (C) 2002 */
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
struct rootDirTocHeader
|
|
||||||
{
|
|
||||||
u16 length; //+00
|
|
||||||
u32 tocLBA; //+02
|
|
||||||
u32 tocLBA_bigend; //+06
|
|
||||||
u32 tocSize; //+0A
|
|
||||||
u32 tocSize_bigend; //+0E
|
|
||||||
u8 dateStamp[8]; //+12
|
|
||||||
u8 reserved[6]; //+1A
|
|
||||||
u8 reserved2; //+20
|
|
||||||
u8 reserved3; //+21
|
|
||||||
}; //+22
|
|
||||||
|
|
||||||
struct asciiDate
|
|
||||||
{
|
|
||||||
char year[4];
|
|
||||||
char month[2];
|
|
||||||
char day[2];
|
|
||||||
char hours[2];
|
|
||||||
char minutes[2];
|
|
||||||
char seconds[2];
|
|
||||||
char hundreths[2];
|
|
||||||
char terminator[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cdVolDesc
|
|
||||||
{
|
|
||||||
u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL
|
|
||||||
u8 volID[5]; // "CD001"
|
|
||||||
u8 reserved2;
|
|
||||||
u8 reserved3;
|
|
||||||
u8 sysIdName[32];
|
|
||||||
u8 volName[32]; // The ISO9660 Volume Name
|
|
||||||
u8 reserved5[8];
|
|
||||||
u32 volSize; // Volume Size
|
|
||||||
u32 volSizeBig; // Volume Size Big-Endian
|
|
||||||
u8 reserved6[32];
|
|
||||||
u32 unknown1;
|
|
||||||
u32 unknown1_bigend;
|
|
||||||
u16 volDescSize; //+80
|
|
||||||
u16 volDescSize_bigend; //+82
|
|
||||||
u32 unknown3; //+84
|
|
||||||
u32 unknown3_bigend; //+88
|
|
||||||
u32 priDirTableLBA; // LBA of Primary Dir Table //+8C
|
|
||||||
u32 reserved7; //+90
|
|
||||||
u32 secDirTableLBA; // LBA of Secondary Dir Table //+94
|
|
||||||
u32 reserved8; //+98
|
|
||||||
struct rootDirTocHeader rootToc;
|
|
||||||
u8 volSetName[128];
|
|
||||||
u8 publisherName[128];
|
|
||||||
u8 preparerName[128];
|
|
||||||
u8 applicationName[128];
|
|
||||||
u8 copyrightFileName[37];
|
|
||||||
u8 abstractFileName[37];
|
|
||||||
u8 bibliographyFileName[37];
|
|
||||||
struct asciiDate creationDate;
|
|
||||||
struct asciiDate modificationDate;
|
|
||||||
struct asciiDate effectiveDate;
|
|
||||||
struct asciiDate expirationDate;
|
|
||||||
u8 reserved10;
|
|
||||||
u8 reserved11[1166];
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
externals.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_CDDA
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_CDR
|
|
||||||
|
|
||||||
extern BOOL bIsOpen;
|
|
||||||
extern BOOL bCDDAPlay;
|
|
||||||
extern int iCDROK;
|
|
||||||
extern char *libraryName;
|
|
||||||
extern int iCheckTrayStatus;
|
|
||||||
extern void *fdump;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_PEOPS
|
|
||||||
|
|
||||||
extern HINSTANCE hInst;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_CFG
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_GENERIC
|
|
||||||
|
|
||||||
extern int iCD_AD;
|
|
||||||
extern int iCD_TA;
|
|
||||||
extern int iCD_LU;
|
|
||||||
extern int iRType;
|
|
||||||
extern int iUseSpeedLimit;
|
|
||||||
extern int iSpeedLimit;
|
|
||||||
extern int iNoWait;
|
|
||||||
extern int iMaxRetry;
|
|
||||||
extern int iShowReadErr;
|
|
||||||
extern HANDLE hEvent;
|
|
||||||
extern HINSTANCE hASPI;
|
|
||||||
extern READFUNC pReadFunc;
|
|
||||||
extern DEINITFUNC pDeInitFunc;
|
|
||||||
extern int iInterfaceMode;
|
|
||||||
extern int iWantedBlockSize;
|
|
||||||
extern int iUsedBlockSize;
|
|
||||||
extern int iUsedMode;
|
|
||||||
extern int iBlockDump;
|
|
||||||
|
|
||||||
extern DWORD (*pGetASPI32SupportInfo)(void);
|
|
||||||
extern DWORD (*pSendASPI32Command)(LPSRB);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_IOCTL
|
|
||||||
|
|
||||||
extern HANDLE hIOCTL;
|
|
||||||
extern DWORD dwIOCTLAttr;
|
|
||||||
extern OVERLAPPED ovcIOCTL;
|
|
||||||
extern SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptIOCTL;
|
|
||||||
extern RAW_READ_INFO rawIOCTL;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_PPF
|
|
||||||
|
|
||||||
extern int iUsePPF;
|
|
||||||
extern char szPPF[];
|
|
||||||
extern PPF_CACHE * ppfCache;
|
|
||||||
extern PPF_DATA * ppfHead;
|
|
||||||
extern int iPPFNum;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_READ
|
|
||||||
|
|
||||||
extern READTRACKFUNC pReadTrackFunc;
|
|
||||||
extern GETPTRFUNC pGetPtrFunc;
|
|
||||||
|
|
||||||
extern int iUseCaching;
|
|
||||||
extern int iUseDataCache;
|
|
||||||
extern int iTryAsync;
|
|
||||||
extern int iBufSel;
|
|
||||||
|
|
||||||
extern unsigned char * pMainBuffer;
|
|
||||||
extern unsigned char * pCurrReadBuf;
|
|
||||||
extern unsigned char * pFirstReadBuf;
|
|
||||||
extern unsigned char * pAsyncBuffer;
|
|
||||||
|
|
||||||
extern unsigned long lMaxAddr;
|
|
||||||
extern unsigned long lLastAddr;
|
|
||||||
extern unsigned long lLastAsyncAddr;
|
|
||||||
|
|
||||||
extern unsigned char * ptrBuffer[];
|
|
||||||
extern unsigned char * pAsyncFirstReadBuf[];
|
|
||||||
extern unsigned long lLastAccessedAddr;
|
|
||||||
extern int iLastAccessedMode;
|
|
||||||
|
|
||||||
extern HANDLE hReadThread;
|
|
||||||
extern BOOL bThreadEnded;
|
|
||||||
extern HANDLE hThreadEvent[];
|
|
||||||
extern HANDLE hThreadMutex[];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_SCSI
|
|
||||||
|
|
||||||
extern SRB_ExecSCSICmd sx;
|
|
||||||
extern BOOL bDoWaiting;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_SUB
|
|
||||||
|
|
||||||
extern unsigned char * pCurrSubBuf;
|
|
||||||
extern int iUseSubReading;
|
|
||||||
extern char szSUBF[];
|
|
||||||
extern SUB_CACHE * subCache;
|
|
||||||
extern SUB_DATA * subHead;
|
|
||||||
extern int iSUBNum;
|
|
||||||
extern unsigned char SubCData[];
|
|
||||||
extern unsigned char SubAData[];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_TOC
|
|
||||||
|
|
||||||
extern TOC sTOC;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,52 +0,0 @@
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
- cdr.c / cdr.h
|
|
||||||
main plugin interface funcs
|
|
||||||
|
|
||||||
- cdda.c / cdda.h
|
|
||||||
audio playing funcs
|
|
||||||
|
|
||||||
- cfg.c / cfg.h
|
|
||||||
configuration dialogs/file reading funcs
|
|
||||||
|
|
||||||
- cdvdPeops.*
|
|
||||||
Windows dll related files (including msvc/devc++ project files)
|
|
||||||
|
|
||||||
- generic.c / generic.h
|
|
||||||
generic stuff
|
|
||||||
|
|
||||||
- ioctrl.c / ioctrl.h
|
|
||||||
w2k/xp ioctl functions
|
|
||||||
|
|
||||||
- ppf.c / ppf.h
|
|
||||||
ppf caching funcs
|
|
||||||
|
|
||||||
- read.c / read.h
|
|
||||||
the different read caching modes
|
|
||||||
|
|
||||||
- scsi.c / scsi.h
|
|
||||||
all the used scsi commands
|
|
||||||
|
|
||||||
- stdafx.h
|
|
||||||
main include file
|
|
||||||
|
|
||||||
- sub.c / sub.h
|
|
||||||
sub data caching
|
|
||||||
|
|
||||||
- toc.c / toc.h
|
|
||||||
toc related funcs
|
|
||||||
|
|
||||||
- externals.h
|
|
||||||
generic defines/external vars
|
|
||||||
|
|
||||||
- defines.h
|
|
||||||
typedef structs/defines/inline funcs
|
|
||||||
|
|
||||||
- resource.h
|
|
||||||
Windows resource header
|
|
||||||
|
|
||||||
- i386.asm
|
|
||||||
NASM funcs
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
|
@ -1,386 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
generic.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/12/25 - Pete
|
|
||||||
// - repaired time2addr/addr2time
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_GENERIC
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int iCD_AD=-1; // drive address
|
|
||||||
int iCD_TA=-1;
|
|
||||||
int iCD_LU=-1;
|
|
||||||
int iRType=0; // read mode
|
|
||||||
int iUseSpeedLimit=0; // speed limit use
|
|
||||||
int iSpeedLimit=2; // speed 2x
|
|
||||||
int iNoWait=0; // wait
|
|
||||||
int iMaxRetry=5; // retry on error
|
|
||||||
int iShowReadErr=0; // show msg on error
|
|
||||||
HANDLE hEvent=NULL; // global event
|
|
||||||
HINSTANCE hASPI=NULL; // aspi lib
|
|
||||||
READFUNC pReadFunc=NULL; // read func
|
|
||||||
DEINITFUNC pDeInitFunc=NULL; // deinit func
|
|
||||||
int iInterfaceMode=1; // interface (aspi/ioctrlscsi/ioctrlraw)
|
|
||||||
int iWantedBlockSize=2352;
|
|
||||||
int iUsedBlockSize=2352;
|
|
||||||
int iUsedMode=CDVD_MODE_2352;
|
|
||||||
int iBlockDump=0;
|
|
||||||
|
|
||||||
DWORD (*pGetASPI32SupportInfo)(void); // ptrs to aspi funcs
|
|
||||||
DWORD (*pSendASPI32Command)(LPSRB);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void addr2time(unsigned long addr, unsigned char *time)
|
|
||||||
{
|
|
||||||
addr+=150;
|
|
||||||
time[3] = (unsigned char)(addr%75);
|
|
||||||
addr/=75;
|
|
||||||
time[2]=(unsigned char)(addr%60);
|
|
||||||
addr/=60;
|
|
||||||
time[1]=(unsigned char)(addr%100);
|
|
||||||
time[0]=(unsigned char)(addr/100);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addr2timeB(unsigned long addr, unsigned char *time)
|
|
||||||
{
|
|
||||||
time[3] = itob((unsigned char)(addr%75));
|
|
||||||
addr/=75;
|
|
||||||
time[2]=itob((unsigned char)(addr%60));
|
|
||||||
addr/=60;
|
|
||||||
time[1]=itob((unsigned char)(addr%100));
|
|
||||||
time[0]=itob((unsigned char)(addr/100));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long time2addr(unsigned char *time)
|
|
||||||
{
|
|
||||||
unsigned long addr;
|
|
||||||
|
|
||||||
addr = time[0]*100;
|
|
||||||
addr += time[1];
|
|
||||||
addr *= 60;
|
|
||||||
|
|
||||||
addr = (addr + time[2])*75;
|
|
||||||
addr += time[3];
|
|
||||||
addr -= 150;
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long time2addrB(unsigned char *time)
|
|
||||||
{
|
|
||||||
unsigned long addr;
|
|
||||||
|
|
||||||
addr = (btoi(time[0]))*100;
|
|
||||||
addr += btoi(time[1]);
|
|
||||||
addr *= 60;
|
|
||||||
addr = (addr + btoi(time[2]))*75;
|
|
||||||
addr += btoi(time[3]);
|
|
||||||
addr -= 150;
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _GCC
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
unsigned long reOrder(unsigned long value)
|
|
||||||
{
|
|
||||||
return ((value&0xff)<<24)|((value&0xff00)<<8)|((value&0xff0000)>>8)|(value>>24);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
unsigned long reOrder(unsigned long value)
|
|
||||||
{
|
|
||||||
#pragma warning (disable: 4035)
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
mov eax,value
|
|
||||||
bswap eax
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CreateGenEvent(void)
|
|
||||||
{
|
|
||||||
hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void FreeGenEvent(void)
|
|
||||||
{
|
|
||||||
if(hEvent) CloseHandle(hEvent);
|
|
||||||
hEvent=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DWORD WaitGenEvent(DWORD dwMS)
|
|
||||||
{
|
|
||||||
if(hASPI) // aspi event
|
|
||||||
return WaitForSingleObject(hEvent,dwMS);
|
|
||||||
else
|
|
||||||
{ // ioctl overlapped (always waiting til finished, dwMS not used)
|
|
||||||
DWORD dwR=0;
|
|
||||||
GetOverlappedResult(hIOCTL,&ovcIOCTL,&dwR,TRUE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void LockGenCDAccess(void)
|
|
||||||
{
|
|
||||||
if(hReadThread) // thread mode?
|
|
||||||
WaitForSingleObject(hThreadMutex[0],INFINITE); // -> wait until all reading is done
|
|
||||||
else // async prefetch?
|
|
||||||
if(bDoWaiting) // -> async operation has to finish first
|
|
||||||
{WaitGenEvent(0xFFFFFFFF);bDoWaiting=FALSE;}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void UnlockGenCDAccess(void)
|
|
||||||
{
|
|
||||||
if(hReadThread) // thread mode?
|
|
||||||
ReleaseMutex(hThreadMutex[0]); // -> we are finished with our special command, now reading can go on
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void WaitUntilDriveIsReady(void)
|
|
||||||
{
|
|
||||||
if(iNoWait==0)
|
|
||||||
{
|
|
||||||
while(TestSCSIUnitReady()==0) Sleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SetGenCDSpeed(int iReset)
|
|
||||||
{
|
|
||||||
if(iUseSpeedLimit)
|
|
||||||
{
|
|
||||||
if(bDoWaiting) // still a command running? wait
|
|
||||||
{WaitGenEvent(0xFFFFFFFF);bDoWaiting=FALSE;}
|
|
||||||
|
|
||||||
if(iReset) SetSCSISpeed(0xFFFF);
|
|
||||||
else
|
|
||||||
if(SetSCSISpeed(176*iSpeedLimit)<=0)
|
|
||||||
{
|
|
||||||
MessageBox(GetActiveWindow(),
|
|
||||||
"Failure: cannot change the drive speed!",
|
|
||||||
"cdvdPeops... speed limitation",
|
|
||||||
MB_OK|MB_ICONEXCLAMATION);
|
|
||||||
iUseSpeedLimit=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// checks, which direct subchannel reading type is supported
|
|
||||||
|
|
||||||
void GetBESubReadFunc(void)
|
|
||||||
{
|
|
||||||
unsigned char * pB=(unsigned char *)malloc(4096);
|
|
||||||
|
|
||||||
pReadFunc = ReadSCSI_BE_Sub; // pre-init read func
|
|
||||||
|
|
||||||
WaitUntilDriveIsReady(); // wait before first read
|
|
||||||
|
|
||||||
ReadSub_BE_2(0,pB,1); // first (unchecked) read
|
|
||||||
if(!ReadSub_BE_2(0,pB,1)) // read again, and check this time
|
|
||||||
{ // -> read failed?
|
|
||||||
if(ReadSub_BE_2_1(0,pB,1)) // -> try different sub reading
|
|
||||||
{ // --> success? mmm... let us check the data
|
|
||||||
DecodeSub_BE_2_1(pB+2352); // --> decode sub
|
|
||||||
if(*(pB+2352)==0x41) // --> check the first decoded byte
|
|
||||||
pReadFunc = ReadSCSI_BE_Sub_1; // ---> wow, byte is ok
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(pB);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int GetGenReadFunc(int iRM)
|
|
||||||
{
|
|
||||||
switch(iRM) // scsi read mode
|
|
||||||
{
|
|
||||||
// ------------------------------------------------ //
|
|
||||||
case MODE_BE_1:
|
|
||||||
case MODE_BE_2:
|
|
||||||
{
|
|
||||||
if(iUseSubReading==1)
|
|
||||||
GetBESubReadFunc();
|
|
||||||
else pReadFunc = ReadSCSI_BE;
|
|
||||||
} break;
|
|
||||||
// ------------------------------------------------ //
|
|
||||||
case MODE_28_1:
|
|
||||||
case MODE_28_2:
|
|
||||||
{
|
|
||||||
if(iUseSubReading==1)
|
|
||||||
pReadFunc = ReadSCSI_28_Sub;
|
|
||||||
else pReadFunc = ReadSCSI_28;
|
|
||||||
} break;
|
|
||||||
// ------------------------------------------------ //
|
|
||||||
case MODE_28_2048:
|
|
||||||
{
|
|
||||||
pReadFunc = ReadSCSI_28_2048;
|
|
||||||
} break;
|
|
||||||
// ------------------------------------------------ //
|
|
||||||
case MODE_28_2048_Ex:
|
|
||||||
{
|
|
||||||
pReadFunc = ReadSCSI_28_2048_Ex;
|
|
||||||
} break;
|
|
||||||
// ------------------------------------------------ //
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
pReadFunc = ReadSCSI_Dummy;
|
|
||||||
} return -3;
|
|
||||||
// ------------------------------------------------ //
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int OpenGenCD(int iA,int iT,int iL)
|
|
||||||
{
|
|
||||||
pDeInitFunc = NULL; // init de-init func
|
|
||||||
pReadFunc = ReadSCSI_Dummy; // init (dummy) read func
|
|
||||||
|
|
||||||
if(iA==-1) return -1; // not configured properly
|
|
||||||
|
|
||||||
// -------------------------------------------------- //
|
|
||||||
|
|
||||||
if(iInterfaceMode>1) // ioctrl interfaces?
|
|
||||||
{
|
|
||||||
OpenIOCTLHandle(iA,iT,iL); // open w2k/xp ioctrl device
|
|
||||||
if(hIOCTL==NULL) return -2; // no cdrom available
|
|
||||||
|
|
||||||
if(iInterfaceMode==3) // special ioctl RAW mode?
|
|
||||||
{ // -> get special reading funcs (non-scsi!)
|
|
||||||
if(iUseSubReading==1)
|
|
||||||
pReadFunc = ReadIOCTL_Raw_Sub;
|
|
||||||
else pReadFunc = ReadIOCTL_Raw;
|
|
||||||
|
|
||||||
WaitUntilDriveIsReady();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // aspi interface?
|
|
||||||
{
|
|
||||||
int iDevice=GetSCSIDevice(iA,iT,iL); // get device type
|
|
||||||
if(iDevice!=DTYPE_CDROM) return -2; // no cdrom? bye
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CheckSCSIReadMode()==SS_COMP)
|
|
||||||
WaitUntilDriveIsReady();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CloseIOCTLHandle();
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CloseGenCD(void)
|
|
||||||
{
|
|
||||||
iCDROK=0; // no more cd available
|
|
||||||
if(pDeInitFunc) pDeInitFunc(); // deinit, if needed
|
|
||||||
pDeInitFunc = NULL;
|
|
||||||
pReadFunc = ReadSCSI_Dummy;
|
|
||||||
CloseIOCTLHandle(); // close ioctl drive file (if used)
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void OpenGenInterface(void)
|
|
||||||
{
|
|
||||||
hASPI=NULL;
|
|
||||||
|
|
||||||
if(iInterfaceMode==0) return; // no interface? no fun
|
|
||||||
else
|
|
||||||
if(iInterfaceMode==1) // aspi
|
|
||||||
{
|
|
||||||
hASPI=LoadLibrary("WNASPI32.DLL");
|
|
||||||
if(hASPI)
|
|
||||||
{
|
|
||||||
pGetASPI32SupportInfo =
|
|
||||||
(DWORD(*)(void)) GetProcAddress(hASPI,"GetASPI32SupportInfo");
|
|
||||||
pSendASPI32Command =
|
|
||||||
(DWORD(*)(LPSRB))GetProcAddress(hASPI,"SendASPI32Command");
|
|
||||||
|
|
||||||
if(!pGetASPI32SupportInfo || !pSendASPI32Command)
|
|
||||||
{
|
|
||||||
iInterfaceMode=0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // ioctl
|
|
||||||
{
|
|
||||||
if(iInterfaceMode<2 || iInterfaceMode>3) iInterfaceMode=2;
|
|
||||||
pGetASPI32SupportInfo = NULL;
|
|
||||||
pSendASPI32Command = IOCTLSendASPI32Command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CloseGenInterface(void)
|
|
||||||
{
|
|
||||||
pGetASPI32SupportInfo=NULL; // clear funcs
|
|
||||||
pSendASPI32Command=NULL;
|
|
||||||
|
|
||||||
if(hASPI) // free aspi
|
|
||||||
{
|
|
||||||
FreeLibrary(hASPI);
|
|
||||||
hASPI=NULL;
|
|
||||||
}
|
|
||||||
else CloseIOCTLHandle(); // or close ioctl file
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int GetGenCDDrives(char * pDList)
|
|
||||||
{
|
|
||||||
if(hASPI) return GetSCSICDDrives(pDList); // aspi? use it
|
|
||||||
return GetIOCTLCDDrives(pDList); // or use ioctl
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,41 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
generic.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void CreateGenEvent(void);
|
|
||||||
void FreeGenEvent(void);
|
|
||||||
DWORD WaitGenEvent(DWORD dwMS);
|
|
||||||
void LockGenCDAccess(void);
|
|
||||||
void UnlockGenCDAccess(void);
|
|
||||||
void WaitUntilDriveIsReady(void);
|
|
||||||
void SetGenCDSpeed(int iReset);
|
|
||||||
void GetBESubReadFunc(void);
|
|
||||||
int GetGenReadFunc(int iRM);
|
|
||||||
int OpenGenCD(int iA,int iT,int iL);
|
|
||||||
void CloseGenCD(void);
|
|
||||||
void OpenGenInterface(void);
|
|
||||||
void CloseGenInterface(void);
|
|
||||||
int GetGenCDDrives(char * pDList);
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
; i386.asm - description
|
|
||||||
; -------------------
|
|
||||||
; begin : Sun Nov 08 2001
|
|
||||||
; copyright : (C) 2001 by Pete Bernert
|
|
||||||
; email : BlackDove@addcom.de
|
|
||||||
|
|
||||||
; This program is free software; you can redistribute it and/or modify *
|
|
||||||
; it under the terms of the GNU General Public License as published by *
|
|
||||||
; the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
; (at your option) any later version. See also the license.txt file for *
|
|
||||||
; additional informations. *
|
|
||||||
|
|
||||||
|
|
||||||
bits 32
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
%include "macros.inc"
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
|
||||||
NEWSYM i386_reOrder
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
mov eax, [ebp+8]
|
|
||||||
bswap eax
|
|
||||||
|
|
||||||
mov esp, ebp
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
ioctrl.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void OpenIOCTLHandle(int iA,int iT,int iL);
|
|
||||||
void CloseIOCTLHandle(void);
|
|
||||||
char MapIOCTLDriveLetter(int iA,int iT,int iL);
|
|
||||||
int GetIOCTLCDDrives(char * pDList);
|
|
||||||
HANDLE OpenIOCTLFile(char cLetter,BOOL bAsync);
|
|
||||||
void GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL);
|
|
||||||
DWORD IOCTLSendASPI32Command(LPSRB pSrb);
|
|
||||||
DWORD ReadIOCTL_Raw(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD ReadIOCTL_Raw_Sub(BOOL bWait,FRAMEBUF * f);
|
|
|
@ -1,738 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
//#include <zlib.h>
|
|
||||||
|
|
||||||
#define __MSCW32__
|
|
||||||
#ifdef __WIN32__
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "PS2Etypes.h"
|
|
||||||
//#include "CDVDiso.h"
|
|
||||||
#include "libiso.h"
|
|
||||||
|
|
||||||
/* some structs from libcdvd by Hiryu & Sjeep (C) 2002 */
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct rootDirTocHeader
|
|
||||||
{
|
|
||||||
u16 length; //+00
|
|
||||||
u32 tocLBA; //+02
|
|
||||||
u32 tocLBA_bigend; //+06
|
|
||||||
u32 tocSize; //+0A
|
|
||||||
u32 tocSize_bigend; //+0E
|
|
||||||
u8 dateStamp[8]; //+12
|
|
||||||
u8 reserved[6]; //+1A
|
|
||||||
u8 reserved2; //+20
|
|
||||||
u8 reserved3; //+21
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
}; //+22
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct asciiDate
|
|
||||||
{
|
|
||||||
char year[4];
|
|
||||||
char month[2];
|
|
||||||
char day[2];
|
|
||||||
char hours[2];
|
|
||||||
char minutes[2];
|
|
||||||
char seconds[2];
|
|
||||||
char hundreths[2];
|
|
||||||
char terminator[1];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct cdVolDesc
|
|
||||||
{
|
|
||||||
u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL
|
|
||||||
u8 volID[5]; // "CD001"
|
|
||||||
u8 reserved2;
|
|
||||||
u8 reserved3;
|
|
||||||
u8 sysIdName[32];
|
|
||||||
u8 volName[32]; // The ISO9660 Volume Name
|
|
||||||
u8 reserved5[8];
|
|
||||||
u32 volSize; // Volume Size
|
|
||||||
u32 volSizeBig; // Volume Size Big-Endian
|
|
||||||
u8 reserved6[32];
|
|
||||||
u32 unknown1;
|
|
||||||
u32 unknown1_bigend;
|
|
||||||
u16 volDescSize; //+80
|
|
||||||
u16 volDescSize_bigend; //+82
|
|
||||||
u32 unknown3; //+84
|
|
||||||
u32 unknown3_bigend; //+88
|
|
||||||
u32 priDirTableLBA; // LBA of Primary Dir Table //+8C
|
|
||||||
u32 reserved7; //+90
|
|
||||||
u32 secDirTableLBA; // LBA of Secondary Dir Table //+94
|
|
||||||
u32 reserved8; //+98
|
|
||||||
struct rootDirTocHeader rootToc;
|
|
||||||
u8 volSetName[128];
|
|
||||||
u8 publisherName[128];
|
|
||||||
u8 preparerName[128];
|
|
||||||
u8 applicationName[128];
|
|
||||||
u8 copyrightFileName[37];
|
|
||||||
u8 abstractFileName[37];
|
|
||||||
u8 bibliographyFileName[37];
|
|
||||||
struct asciiDate creationDate;
|
|
||||||
struct asciiDate modificationDate;
|
|
||||||
struct asciiDate effectiveDate;
|
|
||||||
struct asciiDate expirationDate;
|
|
||||||
u8 reserved10;
|
|
||||||
u8 reserved11[1166];
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} __attribute__((packed));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WIN32__
|
|
||||||
void *_openfile(const char *filename, int flags) {
|
|
||||||
HANDLE handle;
|
|
||||||
|
|
||||||
// printf("_openfile %s, %d\n", filename, flags & O_RDONLY);
|
|
||||||
if (flags & O_WRONLY) {
|
|
||||||
int _flags = CREATE_NEW;
|
|
||||||
if (flags & O_CREAT) _flags = CREATE_ALWAYS;
|
|
||||||
handle = CreateFile(filename, GENERIC_WRITE, 0, NULL, _flags, 0, NULL);
|
|
||||||
} else {
|
|
||||||
handle = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return handle == INVALID_HANDLE_VALUE ? NULL : handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 _tellfile(void *handle) {
|
|
||||||
u64 ofs;
|
|
||||||
DWORD *_ofs = (DWORD*)&ofs;
|
|
||||||
_ofs[1] = 0;
|
|
||||||
_ofs[0] = SetFilePointer(handle, 0, &_ofs[1], FILE_CURRENT);
|
|
||||||
return ofs;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _seekfile(void *handle, u64 offset, int whence) {
|
|
||||||
u64 ofs = (u64)offset;
|
|
||||||
DWORD *_ofs = (DWORD*)&ofs;
|
|
||||||
// printf("_seekfile %p, %d_%d\n", handle, _ofs[1], _ofs[0]);
|
|
||||||
if (whence == SEEK_SET) {
|
|
||||||
SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_BEGIN);
|
|
||||||
} else {
|
|
||||||
SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_END);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _readfile(void *handle, void *dst, int size) {
|
|
||||||
DWORD ret;
|
|
||||||
|
|
||||||
// printf("_readfile %p %d\n", handle, size);
|
|
||||||
ReadFile(handle, dst, size, &ret, NULL);
|
|
||||||
// printf("_readfile ret %d; %d\n", ret, GetLastError());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _writefile(void *handle, void *src, int size) {
|
|
||||||
DWORD ret;
|
|
||||||
|
|
||||||
// printf("_writefile %p, %d\n", handle, size);
|
|
||||||
// _seekfile(handle, _tellfile(handle));
|
|
||||||
WriteFile(handle, src, size, &ret, NULL);
|
|
||||||
// printf("_writefile ret %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _closefile(void *handle) {
|
|
||||||
CloseHandle(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void *_openfile(const char *filename, int flags) {
|
|
||||||
printf("_openfile %s %x\n", filename, flags);
|
|
||||||
if (flags & O_WRONLY)
|
|
||||||
return fopen(filename, "wb");
|
|
||||||
else return fopen(filename, "rb");
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 _tellfile(void *handle) {
|
|
||||||
return ftell(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _seekfile(void *handle, u64 offset, int whence) {
|
|
||||||
return fseek(handle, offset, whence);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _readfile(void *handle, void *dst, int size) {
|
|
||||||
return fread(dst, 1, size, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _writefile(void *handle, void *src, int size) {
|
|
||||||
return fwrite(src, 1, size, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _closefile(void *handle) {
|
|
||||||
fclose(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int detect(isoFile *iso) {
|
|
||||||
char buf[2448];
|
|
||||||
struct cdVolDesc *volDesc;
|
|
||||||
|
|
||||||
if (isoReadBlock(iso, buf, 16) == -1) return -1;
|
|
||||||
volDesc = (struct cdVolDesc *)(buf + 24);
|
|
||||||
if (strncmp(volDesc->volID, "CD001", 5)) return 0;
|
|
||||||
|
|
||||||
if (volDesc->rootToc.tocSize == 2048) {
|
|
||||||
iso->type = ISOTYPE_CD;
|
|
||||||
} else {
|
|
||||||
iso->type = ISOTYPE_DVD;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isoReadZtable(isoFile *iso) {
|
|
||||||
void *handle;
|
|
||||||
char table[256];
|
|
||||||
int size;
|
|
||||||
|
|
||||||
sprintf(table, "%s.table", iso->filename);
|
|
||||||
handle = _openfile(table, O_RDONLY);
|
|
||||||
if (handle == NULL) {
|
|
||||||
printf("Error loading %s\n", table);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_seekfile(handle, 0, SEEK_END);
|
|
||||||
size = (int)_tellfile(handle);
|
|
||||||
iso->Ztable = (char*)malloc(size);
|
|
||||||
if (iso->Ztable == NULL) {
|
|
||||||
_closefile(handle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_seekfile(handle, 0, SEEK_SET);
|
|
||||||
_readfile(handle, iso->Ztable, size);
|
|
||||||
_closefile(handle);
|
|
||||||
|
|
||||||
iso->blocks = size / 6;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isoReadZ2table(isoFile *iso) {
|
|
||||||
void *handle;
|
|
||||||
char table[256];
|
|
||||||
u32 *Ztable;
|
|
||||||
int ofs;
|
|
||||||
int size;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
sprintf(table, "%s.table", iso->filename);
|
|
||||||
handle = _openfile(table, O_RDONLY);
|
|
||||||
if (handle == NULL) {
|
|
||||||
printf("Error loading %s\n", table);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_seekfile(handle, 0, SEEK_END);
|
|
||||||
size = (int)_tellfile(handle);
|
|
||||||
Ztable = (u32*)malloc(size);
|
|
||||||
if (Ztable == NULL) {
|
|
||||||
_closefile(handle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_seekfile(handle, 0, SEEK_SET);
|
|
||||||
_readfile(handle, Ztable, size);
|
|
||||||
_closefile(handle);
|
|
||||||
|
|
||||||
iso->Ztable = (char*)malloc(iso->blocks*8);
|
|
||||||
if (iso->Ztable == NULL) {
|
|
||||||
free(Ztable);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ofs=16;
|
|
||||||
for (i=0; i<iso->blocks; i++) {
|
|
||||||
*(u32*)&iso->Ztable[i*8+0] = ofs;
|
|
||||||
*(u32*)&iso->Ztable[i*8+4] = Ztable[i];
|
|
||||||
ofs+= Ztable[i];
|
|
||||||
}
|
|
||||||
free(Ztable);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isoReadDtable(isoFile *iso) {
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
_seekfile(iso->handle, 0, SEEK_END);
|
|
||||||
iso->dtablesize = (int)(_tellfile(iso->handle) - 16) / (iso->blocksize+4);
|
|
||||||
iso->dtable = (u32*)malloc(iso->dtablesize*4);
|
|
||||||
|
|
||||||
for (i=0; i<iso->dtablesize; i++) {
|
|
||||||
_seekfile(iso->handle, 16+(iso->blocksize+4)*i, SEEK_SET);
|
|
||||||
ret = _readfile(iso->handle, &iso->dtable[i], 4);
|
|
||||||
if (ret < 4) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isoDetect(isoFile *iso) { // based on florin's CDVDbin detection code :)
|
|
||||||
char buf[32];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
iso->type = ISOTYPE_ILLEGAL;
|
|
||||||
|
|
||||||
len = strlen(iso->filename);
|
|
||||||
if (len >= 2) {
|
|
||||||
if (!strncmp(iso->filename+(len-2), ".Z", 2)) {
|
|
||||||
iso->flags = ISOFLAGS_Z;
|
|
||||||
iso->blocksize = 2352;
|
|
||||||
_isoReadZtable(iso);
|
|
||||||
return detect(iso) == 1 ? 0 : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_seekfile(iso->handle, 0, SEEK_SET);
|
|
||||||
_readfile(iso->handle, buf, 4);
|
|
||||||
if (strncmp(buf, "BDV2", 4) == 0) {
|
|
||||||
iso->flags = ISOFLAGS_BLOCKDUMP;
|
|
||||||
_readfile(iso->handle, &iso->blocksize, 4);
|
|
||||||
_readfile(iso->handle, &iso->blocks, 4);
|
|
||||||
_readfile(iso->handle, &iso->blockofs, 4);
|
|
||||||
_isoReadDtable(iso);
|
|
||||||
return detect(iso) == 1 ? 0 : -1;
|
|
||||||
} else
|
|
||||||
if (strncmp(buf, "Z V2", 4) == 0) {
|
|
||||||
iso->flags = ISOFLAGS_Z2;
|
|
||||||
_readfile(iso->handle, &iso->blocksize, 4);
|
|
||||||
_readfile(iso->handle, &iso->blocks, 4);
|
|
||||||
_readfile(iso->handle, &iso->blockofs, 4);
|
|
||||||
_isoReadZ2table(iso);
|
|
||||||
return detect(iso) == 1 ? 0 : -1;
|
|
||||||
} else {
|
|
||||||
iso->blocks = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ISO 2048
|
|
||||||
iso->blocksize = 2048; iso->offset = 0; iso->blockofs = 24;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// RAW 2336
|
|
||||||
iso->blocksize = 2336; iso->offset = 0; iso->blockofs = 16;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// RAW 2352
|
|
||||||
iso->blocksize = 2352; iso->offset = 0; iso->blockofs = 0;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// RAWQ 2448
|
|
||||||
iso->blocksize = 2448; iso->offset = 0; iso->blockofs = 0;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// NERO ISO 2048
|
|
||||||
iso->blocksize = 2048; iso->offset = 150*2048; iso->blockofs = 24;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// NERO RAW 2352
|
|
||||||
iso->blocksize = 2352; iso->offset = 150*2048; iso->blockofs = 0;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// NERO RAWQ 2448
|
|
||||||
iso->blocksize = 2448; iso->offset = 150*2048; iso->blockofs = 0;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// ISO 2048
|
|
||||||
iso->blocksize = 2048; iso->offset = -8; iso->blockofs = 24;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// RAW 2352
|
|
||||||
iso->blocksize = 2352; iso->offset = -8; iso->blockofs = 0;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
// RAWQ 2448
|
|
||||||
iso->blocksize = 2448; iso->offset = -8; iso->blockofs = 0;
|
|
||||||
if (detect(iso) == 1) return 0;
|
|
||||||
|
|
||||||
iso->offset = 0;
|
|
||||||
iso->blocksize = 2352;
|
|
||||||
iso->type = ISOTYPE_AUDIO;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
isoFile *isoOpen(const char *filename) {
|
|
||||||
isoFile *iso;
|
|
||||||
|
|
||||||
iso = (isoFile*)malloc(sizeof(isoFile));
|
|
||||||
if (iso == NULL) return NULL;
|
|
||||||
|
|
||||||
memset(iso, 0, sizeof(isoFile));
|
|
||||||
strcpy(iso->filename, filename);
|
|
||||||
|
|
||||||
iso->handle = _openfile(iso->filename, O_RDONLY);
|
|
||||||
if (iso->handle == NULL) {
|
|
||||||
printf("Error loading %s\n", iso->filename);
|
|
||||||
free(iso);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isoDetect(iso) == -1) return NULL;
|
|
||||||
|
|
||||||
if (iso->flags & (ISOFLAGS_Z | ISOFLAGS_Z2 | ISOFLAGS_BLOCKDUMP)) {
|
|
||||||
} else {
|
|
||||||
_seekfile(iso->handle, 0, SEEK_END);
|
|
||||||
iso->blocks = (u32)((_tellfile(iso->handle) - iso->offset) /
|
|
||||||
(iso->blocksize));
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (strlen(IsoFile) > 3 &&
|
|
||||||
!strncmp(IsoFile + (strlen(IsoFile) - 3), "I00", 3)) {
|
|
||||||
int i;
|
|
||||||
int llsn=0;
|
|
||||||
|
|
||||||
for (i=0; i<8; i++) {
|
|
||||||
IsoFile[strlen(IsoFile) - 1] = '0' + i;
|
|
||||||
if (stat(IsoFile, &buf) == -1) break;
|
|
||||||
cdIndexs[i].slsn = llsn;
|
|
||||||
llsn+= buf.st_size / cdblocksize;
|
|
||||||
cdIndexs[i].elsn = llsn-1;
|
|
||||||
cdHandle[i] = fopen(IsoFile, "rb");
|
|
||||||
if (cdHandle[i] == NULL) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == 0) {
|
|
||||||
SysMessage("Error loading %s\n", IsoFile);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fmode = 3;
|
|
||||||
} else*//* {
|
|
||||||
iso->handle = _openfile(iso->filename, O_RDONLY);
|
|
||||||
if (iso->handle == NULL) {
|
|
||||||
printf("Error loading %s\n", iso->filename);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
printf("isoOpen: %s ok\n", iso->filename);
|
|
||||||
printf("offset = %d\n", iso->offset);
|
|
||||||
printf("blockofs = %d\n", iso->blockofs);
|
|
||||||
printf("blocksize = %d\n", iso->blocksize);
|
|
||||||
printf("blocks = %d\n", iso->blocks);
|
|
||||||
printf("type = %d\n", iso->type);
|
|
||||||
|
|
||||||
return iso;
|
|
||||||
}
|
|
||||||
|
|
||||||
isoFile *isoCreate(const char *filename, int flags) {
|
|
||||||
isoFile *iso;
|
|
||||||
char Zfile[256];
|
|
||||||
|
|
||||||
iso = (isoFile*)malloc(sizeof(isoFile));
|
|
||||||
if (iso == NULL) return NULL;
|
|
||||||
|
|
||||||
memset(iso, 0, sizeof(isoFile));
|
|
||||||
strcpy(iso->filename, filename);
|
|
||||||
iso->flags = flags;
|
|
||||||
iso->offset = 0;
|
|
||||||
iso->blockofs = 24;
|
|
||||||
iso->blocksize = CD_FRAMESIZE_RAW;
|
|
||||||
iso->blocksize = 2048;
|
|
||||||
|
|
||||||
if (iso->flags & (ISOFLAGS_Z | ISOFLAGS_Z2)) {
|
|
||||||
sprintf(Zfile, "%s.table", iso->filename);
|
|
||||||
iso->htable = _openfile(Zfile, O_WRONLY);
|
|
||||||
if (iso->htable == NULL) {
|
|
||||||
free(iso);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iso->handle = _openfile(iso->filename, O_WRONLY);
|
|
||||||
if (iso->handle == NULL) {
|
|
||||||
printf("Error loading %s\n", iso->filename);
|
|
||||||
free(iso);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
printf("isoCreate: %s ok\n", iso->filename);
|
|
||||||
printf("offset = %d\n", iso->offset);
|
|
||||||
|
|
||||||
return iso;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks) {
|
|
||||||
iso->blocksize = blocksize;
|
|
||||||
iso->blocks = blocks;
|
|
||||||
iso->blockofs = blockofs;
|
|
||||||
printf("blockofs = %d\n", iso->blockofs);
|
|
||||||
printf("blocksize = %d\n", iso->blocksize);
|
|
||||||
printf("blocks = %d\n", iso->blocks);
|
|
||||||
if (iso->flags & ISOFLAGS_Z2) {
|
|
||||||
if (_writefile(iso->handle, "Z V2", 4) < 4) return -1;
|
|
||||||
if (_writefile(iso->handle, &blocksize, 4) < 4) return -1;
|
|
||||||
if (_writefile(iso->handle, &blocks, 4) < 4) return -1;
|
|
||||||
if (_writefile(iso->handle, &blockofs, 4) < 4) return -1;
|
|
||||||
}
|
|
||||||
if (iso->flags & ISOFLAGS_BLOCKDUMP) {
|
|
||||||
if (_writefile(iso->handle, "BDV2", 4) < 4) return -1;
|
|
||||||
if (_writefile(iso->handle, &blocksize, 4) < 4) return -1;
|
|
||||||
if (_writefile(iso->handle, &blocks, 4) < 4) return -1;
|
|
||||||
if (_writefile(iso->handle, &blockofs, 4) < 4) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 MSFtoLSN(u8 *Time) {
|
|
||||||
u32 lsn;
|
|
||||||
|
|
||||||
lsn = Time[2];
|
|
||||||
lsn+=(Time[1] - 2) * 75;
|
|
||||||
lsn+= Time[0] * 75 * 60;
|
|
||||||
return lsn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LSNtoMSF(u8 *Time, s32 lsn) {
|
|
||||||
u8 m, s, f;
|
|
||||||
|
|
||||||
lsn += 150;
|
|
||||||
m = lsn / 4500; // minuten
|
|
||||||
lsn = lsn - m * 4500; // minuten rest
|
|
||||||
s = lsn / 75; // sekunden
|
|
||||||
f = lsn - (s * 75); // sekunden rest
|
|
||||||
Time[0] = itob(m); Time[1] = itob(s); Time[2] = itob(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isoReadBlock(isoFile *iso, char *dst, int lsn) {
|
|
||||||
u64 ofs = (u64)lsn * iso->blocksize + iso->offset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs);
|
|
||||||
memset(dst, 0, iso->blockofs);
|
|
||||||
_seekfile(iso->handle, ofs, SEEK_SET);
|
|
||||||
ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize);
|
|
||||||
if (ret < iso->blocksize) {
|
|
||||||
printf("read error %d\n", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
int _isoReadBlockZ(isoFile *iso, char *dst, int lsn) {
|
|
||||||
u32 pos, p;
|
|
||||||
uLongf size;
|
|
||||||
u8 Zbuf[CD_FRAMESIZE_RAW*2];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoReadBlockZ %d, %d\n", lsn, iso->blocksize);
|
|
||||||
pos = *(unsigned long*)&iso->Ztable[lsn * 6];
|
|
||||||
p = *(unsigned short*)&iso->Ztable[lsn * 6 + 4];
|
|
||||||
// printf("%d, %d\n", pos, p);
|
|
||||||
_seekfile(iso->handle, pos, SEEK_SET);
|
|
||||||
ret = _readfile(iso->handle, Zbuf, p);
|
|
||||||
if (ret < p) {
|
|
||||||
printf("error reading block!!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = CD_FRAMESIZE_RAW;
|
|
||||||
uncompress(dst, &size, Zbuf, p);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isoReadBlockZ2(isoFile *iso, char *dst, int lsn) {
|
|
||||||
u32 pos, p;
|
|
||||||
uLongf size;
|
|
||||||
u8 Zbuf[16*1024];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoReadBlockZ2 %d, %d\n", lsn, iso->blocksize);
|
|
||||||
pos = *(u32*)&iso->Ztable[lsn*8];
|
|
||||||
p = *(u32*)&iso->Ztable[lsn*8+4];
|
|
||||||
// printf("%d, %d\n", pos, p);
|
|
||||||
_seekfile(iso->handle, pos, SEEK_SET);
|
|
||||||
ret = _readfile(iso->handle, Zbuf, p);
|
|
||||||
if (ret < p) {
|
|
||||||
printf("error reading block!!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = iso->blocksize;
|
|
||||||
uncompress(dst + iso->blockofs, &size, Zbuf, p);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int _isoReadBlockD(isoFile *iso, char *dst, int lsn) {
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// printf("_isoReadBlockD %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs);
|
|
||||||
memset(dst, 0, iso->blockofs);
|
|
||||||
for (i=0; i<iso->dtablesize;i++) {
|
|
||||||
if (iso->dtable[i] != lsn) continue;
|
|
||||||
|
|
||||||
_seekfile(iso->handle, 16+i*(iso->blocksize+4)+4, SEEK_SET);
|
|
||||||
ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize);
|
|
||||||
if (ret < iso->blocksize) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
printf("block %d not found in dump\n", lsn);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isoReadBlock(isoFile *iso, char *dst, int lsn) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (lsn > iso->blocks) {
|
|
||||||
printf("isoReadBlock: %d > %d\n", lsn, iso->blocks);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* if (iso->flags & ISOFLAGS_Z) {
|
|
||||||
ret = _isoReadBlockZ(iso, dst, lsn);
|
|
||||||
} else
|
|
||||||
if (iso->flags & ISOFLAGS_Z2) {
|
|
||||||
ret = _isoReadBlockZ2(iso, dst, lsn);
|
|
||||||
} else
|
|
||||||
*/ if (iso->flags & ISOFLAGS_BLOCKDUMP) {
|
|
||||||
ret = _isoReadBlockD(iso, dst, lsn);
|
|
||||||
} else
|
|
||||||
ret = _isoReadBlock(iso, dst, lsn);
|
|
||||||
if (ret == -1) return ret;
|
|
||||||
|
|
||||||
if (iso->type == ISOTYPE_CD) {
|
|
||||||
LSNtoMSF(dst+12, lsn);
|
|
||||||
dst[15] = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int _isoWriteBlock(isoFile *iso, u8 *src, int lsn) {
|
|
||||||
u64 ofs = (u64)lsn * iso->blocksize + iso->offset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs);
|
|
||||||
_seekfile(iso->handle, ofs, SEEK_SET);
|
|
||||||
ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize);
|
|
||||||
// printf("_isoWriteBlock %d\n", ret);
|
|
||||||
if (ret < iso->blocksize) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
int _isoWriteBlockZ(isoFile *iso, u8 *src, int lsn) {
|
|
||||||
u32 pos;
|
|
||||||
uLongf size;
|
|
||||||
u8 Zbuf[CD_FRAMESIZE_RAW];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoWriteBlockZ %d\n", iso->blocksize);
|
|
||||||
size = 2352;
|
|
||||||
compress(Zbuf, &size, src, 2352);
|
|
||||||
// printf("_isoWriteBlockZ %d\n", size);
|
|
||||||
|
|
||||||
pos = (u32)_tellfile(iso->handle);
|
|
||||||
ret = _writefile(iso->htable, (u8*)&pos, 4);
|
|
||||||
if (ret < 4) return -1;
|
|
||||||
ret = _writefile(iso->htable, (u8*)&size, 2);
|
|
||||||
if (ret < 2) return -1;
|
|
||||||
|
|
||||||
ret = _writefile(iso->handle, Zbuf, size);
|
|
||||||
// printf("_isoWriteBlockZ %d\n", ret);
|
|
||||||
if (ret < size) {
|
|
||||||
printf("error writing block!!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isoWriteBlockZ2(isoFile *iso, u8 *src, int lsn) {
|
|
||||||
uLongf size;
|
|
||||||
u8 Zbuf[1024*16];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoWriteBlockZ %d\n", iso->blocksize);
|
|
||||||
size = 1024*16;
|
|
||||||
compress(Zbuf, &size, src + iso->blockofs, iso->blocksize);
|
|
||||||
// printf("_isoWriteBlockZ %d\n", size);
|
|
||||||
|
|
||||||
ret = _writefile(iso->htable, (u8*)&size, 4);
|
|
||||||
if (ret < 4) return -1;
|
|
||||||
ret = _writefile(iso->handle, Zbuf, size);
|
|
||||||
// printf("_isoWriteBlockZ %d\n", ret);
|
|
||||||
if (ret < size) {
|
|
||||||
printf("error writing block!!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int _isoWriteBlockD(isoFile *iso, u8 *src, int lsn) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs);
|
|
||||||
ret = _writefile(iso->handle, &lsn, 4);
|
|
||||||
if (ret < 4) return -1;
|
|
||||||
ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize);
|
|
||||||
// printf("_isoWriteBlock %d\n", ret);
|
|
||||||
if (ret < iso->blocksize) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isoWriteBlock(isoFile *iso, char *src, int lsn) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* if (iso->flags & ISOFLAGS_Z) {
|
|
||||||
ret = _isoWriteBlockZ(iso, src, lsn);
|
|
||||||
} else
|
|
||||||
if (iso->flags & ISOFLAGS_Z2) {
|
|
||||||
ret = _isoWriteBlockZ2(iso, src, lsn);
|
|
||||||
} else
|
|
||||||
*/ if (iso->flags & ISOFLAGS_BLOCKDUMP) {
|
|
||||||
ret = _isoWriteBlockD(iso, src, lsn);
|
|
||||||
} else
|
|
||||||
ret = _isoWriteBlock(iso, src, lsn);
|
|
||||||
if (ret == -1) return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void isoClose(isoFile *iso) {
|
|
||||||
if (iso->handle) {
|
|
||||||
_closefile(iso->handle);
|
|
||||||
}
|
|
||||||
if (iso->htable) {
|
|
||||||
_closefile(iso->htable);
|
|
||||||
}
|
|
||||||
free(iso);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
#ifndef __LIBISO_H__
|
|
||||||
#define __LIBISO_H__
|
|
||||||
|
|
||||||
#ifdef __MSCW32__
|
|
||||||
#pragma warning(disable:4018)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CDVDdefs
|
|
||||||
#include "PS2Etypes.h"
|
|
||||||
#include "PS2Edefs.h"
|
|
||||||
|
|
||||||
#define ISOTYPE_ILLEGAL 0
|
|
||||||
#define ISOTYPE_CD 1
|
|
||||||
#define ISOTYPE_DVD 2
|
|
||||||
#define ISOTYPE_AUDIO 3
|
|
||||||
|
|
||||||
#define ISOFLAGS_Z 0x1
|
|
||||||
#define ISOFLAGS_Z2 0x2
|
|
||||||
#define ISOFLAGS_BLOCKDUMP 0x4
|
|
||||||
|
|
||||||
#define CD_FRAMESIZE_RAW 2352
|
|
||||||
#define DATA_SIZE (CD_FRAMESIZE_RAW-12)
|
|
||||||
|
|
||||||
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
|
|
||||||
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char filename[256];
|
|
||||||
u32 type;
|
|
||||||
u32 flags;
|
|
||||||
u32 offset;
|
|
||||||
u32 blockofs;
|
|
||||||
u32 blocksize;
|
|
||||||
u32 blocks;
|
|
||||||
void *handle;
|
|
||||||
void *htable;
|
|
||||||
char *Ztable;
|
|
||||||
u32 *dtable;
|
|
||||||
int dtablesize;
|
|
||||||
char buffer[CD_FRAMESIZE_RAW * 10];
|
|
||||||
} isoFile;
|
|
||||||
|
|
||||||
|
|
||||||
isoFile *isoOpen(const char *filename);
|
|
||||||
isoFile *isoCreate(const char *filename, int mode);
|
|
||||||
int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks);
|
|
||||||
int isoDetect(isoFile *iso);
|
|
||||||
int isoReadBlock(isoFile *iso, char *dst, int lsn);
|
|
||||||
int isoWriteBlock(isoFile *iso, char *src, int lsn);
|
|
||||||
void isoClose(isoFile *iso);
|
|
||||||
|
|
||||||
void *_openfile(const char *filename, int flags);
|
|
||||||
u64 _tellfile(void *handle);
|
|
||||||
int _seekfile(void *handle, u64 offset, int whence);
|
|
||||||
int _readfile(void *handle, void *dst, int size);
|
|
||||||
int _writefile(void *handle, void *src, int size);
|
|
||||||
void _closefile(void *handle);
|
|
||||||
|
|
||||||
#endif /* __LIBISO_H__ */
|
|
|
@ -1,282 +0,0 @@
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
|
||||||
675 Mass Ave, Cambridge, MA 02139, USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
|
@ -1,40 +0,0 @@
|
||||||
; macros.inc - description
|
|
||||||
; -------------------
|
|
||||||
; begin : Sun Nov 08 2001
|
|
||||||
; based on ZSNES macros.mac
|
|
||||||
; email : linuzappz@pcsx.net
|
|
||||||
|
|
||||||
; This program is free software; you can redistribute it and/or modify *
|
|
||||||
; it under the terms of the GNU General Public License as published by *
|
|
||||||
; the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
; (at your option) any later version. See also the license.txt file for *
|
|
||||||
; additional informations. *
|
|
||||||
|
|
||||||
|
|
||||||
%ifdef __WIN32__
|
|
||||||
|
|
||||||
%imacro EXTSYM 1-*
|
|
||||||
%rep %0
|
|
||||||
extern _%1
|
|
||||||
%define %1 _%1
|
|
||||||
%rotate 1
|
|
||||||
%endrep
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%imacro NEWSYM 1
|
|
||||||
global _%1
|
|
||||||
_%1:
|
|
||||||
%1:
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%else
|
|
||||||
|
|
||||||
%define EXTSYM extern
|
|
||||||
|
|
||||||
%imacro NEWSYM 1
|
|
||||||
global %1
|
|
||||||
%1:
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%endif
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include <windows.h>
|
|
||||||
#define IDC_STATIC -1
|
|
|
@ -1,353 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
ppf.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/02/14 - Pete
|
|
||||||
// - fixed a bug reading PPF3 patches reported by Zydio
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_PPF
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int iUsePPF=0;
|
|
||||||
char szPPF[260];
|
|
||||||
PPF_CACHE * ppfCache=NULL;
|
|
||||||
PPF_DATA * ppfHead=NULL;
|
|
||||||
int iPPFNum=0;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// works like sub cache... using a linked data list, and address array
|
|
||||||
|
|
||||||
void FillPPFCache(void)
|
|
||||||
{
|
|
||||||
PPF_DATA * p;PPF_CACHE * pc;
|
|
||||||
long lastaddr;
|
|
||||||
|
|
||||||
p=ppfHead;
|
|
||||||
lastaddr=-1;
|
|
||||||
iPPFNum=0;
|
|
||||||
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
if(p->addr!=lastaddr) iPPFNum++;
|
|
||||||
lastaddr=p->addr;
|
|
||||||
p=(PPF_DATA *)p->pNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!iPPFNum) return;
|
|
||||||
|
|
||||||
pc=ppfCache=(PPF_CACHE *)malloc(iPPFNum*sizeof(PPF_CACHE));
|
|
||||||
|
|
||||||
iPPFNum--;
|
|
||||||
p=ppfHead;
|
|
||||||
lastaddr=-1;
|
|
||||||
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
if(p->addr!=lastaddr)
|
|
||||||
{
|
|
||||||
pc->addr=p->addr;
|
|
||||||
pc->pNext=(void *)p;
|
|
||||||
pc++;
|
|
||||||
}
|
|
||||||
lastaddr=p->addr;
|
|
||||||
p=(PPF_DATA *)p->pNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void FreePPFCache(void)
|
|
||||||
{
|
|
||||||
PPF_DATA * p=ppfHead;
|
|
||||||
void * pn;
|
|
||||||
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
pn=p->pNext;
|
|
||||||
free(p);
|
|
||||||
p=(PPF_DATA *)pn;
|
|
||||||
}
|
|
||||||
ppfHead=NULL;
|
|
||||||
|
|
||||||
if(ppfCache) free(ppfCache);
|
|
||||||
ppfCache=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CheckPPFCache(long addr,unsigned char * pB)
|
|
||||||
{
|
|
||||||
PPF_CACHE * pcstart, * pcend, * pcpos;
|
|
||||||
|
|
||||||
pcstart=ppfCache;
|
|
||||||
if(addr<pcstart->addr) return;
|
|
||||||
pcend=ppfCache+iPPFNum;
|
|
||||||
if(addr>pcend->addr) return;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(addr==pcend->addr) {pcpos=pcend;break;}
|
|
||||||
|
|
||||||
pcpos=pcstart+(pcend-pcstart)/2;
|
|
||||||
if(pcpos==pcstart) break;
|
|
||||||
if(addr<pcpos->addr)
|
|
||||||
{
|
|
||||||
pcend=pcpos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(addr>pcpos->addr)
|
|
||||||
{
|
|
||||||
pcstart=pcpos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(addr==pcpos->addr)
|
|
||||||
{
|
|
||||||
PPF_DATA * p=(PPF_DATA *)pcpos->pNext;
|
|
||||||
while(p && p->addr==addr)
|
|
||||||
{
|
|
||||||
memcpy(pB+p->pos,p+1,p->anz);
|
|
||||||
p=(PPF_DATA *)p->pNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void AddToPPF(long ladr,long pos,long anz,char * ppfmem)
|
|
||||||
{
|
|
||||||
if(!ppfHead)
|
|
||||||
{
|
|
||||||
ppfHead=(PPF_DATA *)malloc(sizeof(PPF_DATA)+anz);
|
|
||||||
ppfHead->addr=ladr;
|
|
||||||
ppfHead->pNext=NULL;
|
|
||||||
ppfHead->pos=pos;
|
|
||||||
ppfHead->anz=anz;
|
|
||||||
memcpy(ppfHead+1,ppfmem,anz);
|
|
||||||
iPPFNum=1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PPF_DATA * p=ppfHead;
|
|
||||||
PPF_DATA * plast=NULL;
|
|
||||||
PPF_DATA * padd;
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
if(ladr<p->addr) break;
|
|
||||||
if(ladr==p->addr)
|
|
||||||
{
|
|
||||||
while(p && ladr==p->addr && pos>p->pos)
|
|
||||||
{
|
|
||||||
plast=p;
|
|
||||||
p=(PPF_DATA *)p->pNext;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
plast=p;
|
|
||||||
p=(PPF_DATA *)p->pNext;
|
|
||||||
}
|
|
||||||
padd=(PPF_DATA *)malloc(sizeof(PPF_DATA)+anz);
|
|
||||||
padd->addr=ladr;
|
|
||||||
padd->pNext=(void *)p;
|
|
||||||
padd->pos=pos;
|
|
||||||
padd->anz=anz;
|
|
||||||
memcpy(padd+1,ppfmem,anz);
|
|
||||||
iPPFNum++;
|
|
||||||
if(plast==NULL)
|
|
||||||
ppfHead=padd;
|
|
||||||
else plast->pNext=(void *)padd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// build ppf cache, if wanted
|
|
||||||
|
|
||||||
void BuildPPFCache(void)
|
|
||||||
{
|
|
||||||
FILE * ppffile;
|
|
||||||
char buffer[5];
|
|
||||||
char method,undo=0,blockcheck=0;
|
|
||||||
int dizlen, dizyn, dizlensave=0;
|
|
||||||
char ppfmem[512];
|
|
||||||
int count,seekpos, pos;
|
|
||||||
//unsigned char anz;
|
|
||||||
unsigned int anz; // new! avoids stupid overflows
|
|
||||||
long ladr,off,anx;
|
|
||||||
|
|
||||||
ppfHead=NULL;
|
|
||||||
|
|
||||||
if(iUsePPF==0) return; // no ppf cache wanted?
|
|
||||||
if(szPPF[0]==0) return; // no ppf file given?
|
|
||||||
|
|
||||||
ppffile=fopen(szPPF, "rb");
|
|
||||||
if(ppffile==0)
|
|
||||||
{
|
|
||||||
MessageBox(NULL,"No PPF file found!",libraryName,MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer,0,5);
|
|
||||||
fread(buffer, 3, 1, ppffile);
|
|
||||||
|
|
||||||
if(strcmp(buffer,"PPF"))
|
|
||||||
{
|
|
||||||
MessageBox(NULL,"No PPF file format!",libraryName,MB_OK);
|
|
||||||
fclose(ppffile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(ppffile, 5, SEEK_SET);
|
|
||||||
fread(&method, 1, 1,ppffile);
|
|
||||||
|
|
||||||
switch(method)
|
|
||||||
{
|
|
||||||
case 0: // ppf1
|
|
||||||
fseek(ppffile, 0, SEEK_END);
|
|
||||||
count=ftell(ppffile);
|
|
||||||
count-=56;
|
|
||||||
seekpos=56;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // ppf2
|
|
||||||
fseek(ppffile, -8,SEEK_END);
|
|
||||||
|
|
||||||
memset(buffer,0,5);
|
|
||||||
fread(buffer, 4, 1,ppffile);
|
|
||||||
if(strcmp(".DIZ", buffer))
|
|
||||||
{
|
|
||||||
dizyn=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fread(&dizlen, 4, 1, ppffile);
|
|
||||||
dizyn=1;
|
|
||||||
dizlensave=dizlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(ppffile, 56, SEEK_SET);
|
|
||||||
fread(&dizlen, 4, 1,ppffile);
|
|
||||||
fseek(ppffile, 0, SEEK_END);
|
|
||||||
count=ftell(ppffile);
|
|
||||||
if(dizyn==0)
|
|
||||||
{
|
|
||||||
count-=1084;
|
|
||||||
seekpos=1084;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count-=1084;
|
|
||||||
count-=38;
|
|
||||||
count-=dizlensave;
|
|
||||||
seekpos=1084;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // ppf3
|
|
||||||
fseek(ppffile, 57, SEEK_SET);
|
|
||||||
fread(&blockcheck, 1, 1,ppffile);
|
|
||||||
fseek(ppffile, 58, SEEK_SET);
|
|
||||||
fread(&undo, 1, 1,ppffile);
|
|
||||||
|
|
||||||
fseek(ppffile, -6,SEEK_END);
|
|
||||||
memset(buffer,0,5);
|
|
||||||
fread(buffer, 4, 1,ppffile);
|
|
||||||
dizlen=0;
|
|
||||||
if(!strcmp(".DIZ", buffer))
|
|
||||||
{
|
|
||||||
fseek(ppffile, -2,SEEK_END);
|
|
||||||
fread(&dizlen, 2, 1, ppffile);
|
|
||||||
dizlen+=36;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(ppffile, 0, SEEK_END);
|
|
||||||
count=ftell(ppffile);
|
|
||||||
count-=dizlen;
|
|
||||||
|
|
||||||
if(blockcheck)
|
|
||||||
{
|
|
||||||
seekpos=1084;
|
|
||||||
count-=1084;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
seekpos=60;
|
|
||||||
count-=60;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fclose(ppffile);
|
|
||||||
MessageBox(NULL,"Unknown PPF format!",libraryName,MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
do // now do the data reading
|
|
||||||
{
|
|
||||||
fseek(ppffile, seekpos, SEEK_SET);
|
|
||||||
fread(&pos, 4, 1, ppffile);
|
|
||||||
|
|
||||||
if(method==2) fread(buffer, 4, 1, ppffile); // skip 4 bytes on ppf3 (no int64 support here)
|
|
||||||
|
|
||||||
anz=0; // new! init anz (since it's no unsigned char anymore)
|
|
||||||
fread(&anz, 1, 1, ppffile);
|
|
||||||
fread(ppfmem, anz, 1, ppffile);
|
|
||||||
|
|
||||||
ladr=pos/2352;
|
|
||||||
off=pos%2352;
|
|
||||||
|
|
||||||
if(off+anz>2352)
|
|
||||||
{
|
|
||||||
anx=off+anz-2352;
|
|
||||||
anz-=(unsigned char)anx;
|
|
||||||
AddToPPF(ladr+1,0,anx,ppfmem+anz);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddToPPF(ladr,off,anz,ppfmem); // add to link list
|
|
||||||
|
|
||||||
if(method==2) // adjust ppf3 size
|
|
||||||
{
|
|
||||||
if(undo) anz+=anz;
|
|
||||||
anz+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
seekpos=seekpos+5+anz;
|
|
||||||
count=count-5-anz;
|
|
||||||
}
|
|
||||||
while(count!=0); // loop til end
|
|
||||||
|
|
||||||
fclose(ppffile);
|
|
||||||
|
|
||||||
FillPPFCache(); // build address array
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,32 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
ppf.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void FillPPFCache(void);
|
|
||||||
void FreePPFCache(void);
|
|
||||||
void CheckPPFCache(long addr,unsigned char * pB);
|
|
||||||
void AddToPPF(long ladr,long pos,long anz,char * ppfmem);
|
|
||||||
void BuildPPFCache(void);
|
|
||||||
|
|
|
@ -1,910 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
read.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_READ
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
READTRACKFUNC pReadTrackFunc=NULL;
|
|
||||||
GETPTRFUNC pGetPtrFunc=NULL;
|
|
||||||
|
|
||||||
int iUseCaching=0;
|
|
||||||
int iTryAsync=0;
|
|
||||||
int iBufSel=0;
|
|
||||||
|
|
||||||
unsigned char * pMainBuffer=0;
|
|
||||||
unsigned char * pCurrReadBuf=0;
|
|
||||||
unsigned char * pFirstReadBuf=0;
|
|
||||||
unsigned char * pAsyncBuffer=0;
|
|
||||||
|
|
||||||
unsigned long lMaxAddr=0;
|
|
||||||
unsigned long lLastAddr = 0xFFFFFFFF;
|
|
||||||
unsigned long lLastAsyncAddr = 0xFFFFFFFF;
|
|
||||||
unsigned long lNeededAddr = 0xFFFFFFFF;
|
|
||||||
unsigned long lLastAccessedAddr = 0xFFFFFFFF;
|
|
||||||
int iLastAccessedMode=0;
|
|
||||||
|
|
||||||
unsigned char * ptrBuffer[2];
|
|
||||||
unsigned char * pAsyncFirstReadBuf[2];
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXQSIZE 16
|
|
||||||
#define MAXQFETCH 8
|
|
||||||
|
|
||||||
unsigned long lAddrQ[MAXQSIZE];
|
|
||||||
int iQPos=0;
|
|
||||||
int iQIdle=0;
|
|
||||||
int iQLockPos=-1;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// thread helper vars
|
|
||||||
|
|
||||||
HANDLE hReadThread = NULL;
|
|
||||||
BOOL bThreadEnded = FALSE;
|
|
||||||
HANDLE hThreadEvent[3];
|
|
||||||
HANDLE hThreadMutex[2];
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// internal MAXDATACACHE*64KB (4MB) data cache
|
|
||||||
|
|
||||||
#define MAXDATACACHE 64
|
|
||||||
unsigned long lDataCacheAddr[MAXDATACACHE];
|
|
||||||
unsigned char * pDataCacheBuf[MAXDATACACHE];
|
|
||||||
BOOL bDataCacheHit=FALSE;
|
|
||||||
int iUseDataCache=0;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// main init func
|
|
||||||
|
|
||||||
void CreateREADBufs(void)
|
|
||||||
{
|
|
||||||
switch(iUseCaching)
|
|
||||||
{
|
|
||||||
case 4: iUseDataCache = 2; // use a special data cache on threadex reading
|
|
||||||
pReadTrackFunc = DoReadThreadEx;
|
|
||||||
pGetPtrFunc = GetREADThreadExPtr; break;
|
|
||||||
case 3: pReadTrackFunc = DoReadThread;
|
|
||||||
pGetPtrFunc = GetREADThreadPtr; break;
|
|
||||||
case 2: pReadTrackFunc = DoReadAsync;
|
|
||||||
pGetPtrFunc = NULL; break;
|
|
||||||
default: pReadTrackFunc = DoRead;
|
|
||||||
pGetPtrFunc = NULL; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hThreadEvent[0]=NULL; // clear events/mutex
|
|
||||||
hThreadEvent[1]=NULL;
|
|
||||||
hThreadEvent[2]=NULL;
|
|
||||||
hThreadMutex[0]=NULL;
|
|
||||||
hThreadMutex[1]=NULL;
|
|
||||||
|
|
||||||
AllocDataCache(); // build data cache, if wanted
|
|
||||||
|
|
||||||
lLastAddr = 0xFFFFFFFF;
|
|
||||||
lLastAsyncAddr = 0xFFFFFFFF;
|
|
||||||
iBufSel = 0;
|
|
||||||
|
|
||||||
if(iUseCaching) // some caching? need bigger buffer
|
|
||||||
pMainBuffer=(unsigned char *)malloc(MAXCDBUFFER);
|
|
||||||
else pMainBuffer=(unsigned char *)malloc(CDSECTOR+208+96);
|
|
||||||
|
|
||||||
pCurrReadBuf=pFirstReadBuf=pMainBuffer+FRAMEBUFEXTRA;
|
|
||||||
|
|
||||||
if(iUseCaching>=2) // async/thread mode
|
|
||||||
{
|
|
||||||
pAsyncBuffer=(unsigned char *)malloc(MAXCDBUFFER);
|
|
||||||
ptrBuffer[0]=pMainBuffer;
|
|
||||||
ptrBuffer[1]=pAsyncBuffer;
|
|
||||||
pAsyncFirstReadBuf[0]=pFirstReadBuf;
|
|
||||||
pAsyncFirstReadBuf[1]=pAsyncBuffer+FRAMEBUFEXTRA;
|
|
||||||
|
|
||||||
if(iUseCaching>=3) // thread mode
|
|
||||||
{
|
|
||||||
DWORD dw;
|
|
||||||
bThreadEnded = FALSE;
|
|
||||||
|
|
||||||
for(dw=0;dw<3;dw++) // -> create events
|
|
||||||
{
|
|
||||||
hThreadEvent[dw]=CreateEvent(NULL,TRUE,FALSE,NULL);
|
|
||||||
ResetEvent(hThreadEvent[dw]);
|
|
||||||
}
|
|
||||||
for(dw=0;dw<2;dw++) // -> create mutex
|
|
||||||
{
|
|
||||||
hThreadMutex[dw]=CreateMutex(NULL,FALSE,NULL);
|
|
||||||
}
|
|
||||||
if(iUseCaching==3) // -> create thread
|
|
||||||
hReadThread=CreateThread(NULL,0,READThread,0,0,&dw);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(dw=0;dw<MAXQSIZE;dw++) lAddrQ[dw]=0xFFFFFFFF;
|
|
||||||
iQPos=0;
|
|
||||||
iQLockPos=-1;
|
|
||||||
hReadThread=CreateThread(NULL,0,READThreadEx,0,0,&dw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pAsyncBuffer=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void FreeREADBufs(void)
|
|
||||||
{
|
|
||||||
if(hReadThread) // thread?
|
|
||||||
{
|
|
||||||
SetEvent(hThreadEvent[1]); // -> signal: end thread
|
|
||||||
while(!bThreadEnded) {Sleep(5L);} // -> wait til ended
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE);
|
|
||||||
ReleaseMutex(hThreadMutex[1]);
|
|
||||||
hReadThread=NULL; // -> clear handle
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hThreadEvent[0]) CloseHandle(hThreadEvent[0]); // kill events/mutex
|
|
||||||
if(hThreadEvent[1]) CloseHandle(hThreadEvent[1]);
|
|
||||||
if(hThreadEvent[2]) CloseHandle(hThreadEvent[2]);
|
|
||||||
if(hThreadMutex[0]) CloseHandle(hThreadMutex[0]);
|
|
||||||
if(hThreadMutex[1]) CloseHandle(hThreadMutex[1]);
|
|
||||||
|
|
||||||
if(pMainBuffer) free(pMainBuffer); // free main data buf
|
|
||||||
pMainBuffer=NULL;
|
|
||||||
if(pAsyncBuffer) free(pAsyncBuffer); // free async data buf
|
|
||||||
pAsyncBuffer=NULL;
|
|
||||||
|
|
||||||
FreeDataCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// retry on readng error (blocking)
|
|
||||||
|
|
||||||
BOOL bReadRetry(FRAMEBUF * f)
|
|
||||||
{
|
|
||||||
int iRetry=0;
|
|
||||||
|
|
||||||
while (iRetry<iMaxRetry)
|
|
||||||
{
|
|
||||||
if(pReadFunc(TRUE,f)==SS_COMP) break; // try sync read
|
|
||||||
iRetry++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(iRetry==iMaxRetry) // no success?
|
|
||||||
{
|
|
||||||
if(iShowReadErr) // -> tell it to user
|
|
||||||
{
|
|
||||||
char szB[64];
|
|
||||||
wsprintf(szB,"Read error on address %08lx!",f->dwFrame);
|
|
||||||
MessageBox(NULL,szB,libraryName,MB_OK);
|
|
||||||
}
|
|
||||||
return FALSE; // -> tell emu: bad
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// sync modes (caching 0 and 1)
|
|
||||||
// just reads one or more blocks, and always waits until
|
|
||||||
// reading is done
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL DoRead(unsigned long addr)
|
|
||||||
{
|
|
||||||
FRAMEBUF * f;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
if(iUseCaching && // cache block available?
|
|
||||||
lLastAddr!=0xFFFFFFFF &&
|
|
||||||
addr>=lLastAddr && // and addr in block?
|
|
||||||
addr<=(lLastAddr+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
pCurrReadBuf=pFirstReadBuf+ // -> calc data ptr
|
|
||||||
((addr-lLastAddr)*iUsedBlockSize);
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf); // -> apply ppf
|
|
||||||
return TRUE; // -> done
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
if(iUseDataCache && CheckDataCache(addr)) // cache used and data is in cache? set read ptr, if yes
|
|
||||||
return TRUE; // -> also fine
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
f=(FRAMEBUF *)pMainBuffer; // setup read for one sector
|
|
||||||
|
|
||||||
f->dwFrameCnt = 1;
|
|
||||||
f->dwBufLen = iUsedBlockSize;
|
|
||||||
f->dwFrame = addr;
|
|
||||||
|
|
||||||
pCurrReadBuf=pFirstReadBuf;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
if(iUseCaching) // cache block?
|
|
||||||
{
|
|
||||||
if((addr+MAXCACHEBLOCK)<lMaxAddr) // and big read is possible?
|
|
||||||
{
|
|
||||||
f->dwFrameCnt = MAXCACHEBLOCK+1; // -> set bigger read
|
|
||||||
f->dwBufLen = (MAXCACHEBLOCK+1)*iUsedBlockSize;
|
|
||||||
lLastAddr = addr; // -> store addr of block
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lLastAddr=0xFFFFFFFF; // no caching, no block addr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
if(pReadFunc(TRUE,f)!=SS_COMP) // do a waiting read
|
|
||||||
{
|
|
||||||
if(!bReadRetry(f)) return FALSE; // and retry on error
|
|
||||||
}
|
|
||||||
|
|
||||||
if(iUseDataCache && lLastAddr!=0xFFFFFFFF) // data cache used? and whole 64 k read block?
|
|
||||||
AddToDataCache(addr,pFirstReadBuf); // -> add the complete data to cache
|
|
||||||
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf); // apply ppf
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// async mode (caching 2)
|
|
||||||
// this mode works fine with ASPI...
|
|
||||||
// the first read will be done sync, though, only the
|
|
||||||
// additional pre-fetching will be done async...
|
|
||||||
// well, with mdecs most reads will be prefetched, so
|
|
||||||
// speed is good... with IOCTL this mode is more like
|
|
||||||
// a 'double sync' reading, since IOCTL seems always
|
|
||||||
// to be blocking (see also notes for caching mode 3)
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL DoReadAsync(unsigned long addr)
|
|
||||||
{
|
|
||||||
FRAMEBUF * f;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// 1. check if data is in already filled buffer
|
|
||||||
|
|
||||||
if(lLastAddr!=0xFFFFFFFF &&
|
|
||||||
addr>=lLastAddr &&
|
|
||||||
addr<=(lLastAddr+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
pCurrReadBuf=pAsyncFirstReadBuf[iBufSel]+
|
|
||||||
((addr-lLastAddr)*iUsedBlockSize);
|
|
||||||
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf);
|
|
||||||
|
|
||||||
iTryAsync=0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// check data cache
|
|
||||||
|
|
||||||
if(iUseDataCache && CheckDataCache(addr)) // cache used and data is in cache? set read ptr, if yes
|
|
||||||
return TRUE; // -> also fine
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// 2. not in main buffer? wait for async to be finished
|
|
||||||
|
|
||||||
if(bDoWaiting)
|
|
||||||
{
|
|
||||||
WaitGenEvent(0xFFFFFFFF);bDoWaiting=FALSE;
|
|
||||||
if(sx.SRB_Status!=SS_COMP) lLastAsyncAddr=0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// 3. check in asyncbuffer. if yes, swap buffers and do next async read
|
|
||||||
|
|
||||||
if(lLastAsyncAddr!=0xFFFFFFFF &&
|
|
||||||
addr>=lLastAsyncAddr &&
|
|
||||||
addr<=(lLastAsyncAddr+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
int iAsyncSel=iBufSel; // store old buf num
|
|
||||||
if(iBufSel==0) iBufSel=1; else iBufSel=0; // toggle to new num
|
|
||||||
|
|
||||||
lLastAddr=lLastAsyncAddr; // set adr of block
|
|
||||||
pCurrReadBuf=pAsyncFirstReadBuf[iBufSel]+ // set data ptr
|
|
||||||
((addr-lLastAddr)*iUsedBlockSize);
|
|
||||||
|
|
||||||
if(iUseDataCache) // data cache used?
|
|
||||||
AddToDataCache(lLastAddr,pAsyncFirstReadBuf[iBufSel]); // -> add the complete 64k data to cache
|
|
||||||
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf); // apply ppf
|
|
||||||
|
|
||||||
iTryAsync=0; // data was async, reset count
|
|
||||||
addr=lLastAddr+MAXCACHEBLOCK+1; // calc adr of next prefetch
|
|
||||||
if(!((addr+MAXCACHEBLOCK)<lMaxAddr)) // mmm, no whole block can be done... so we do no prefetch at all
|
|
||||||
{lLastAsyncAddr=0xFFFFFFFF;return TRUE;}
|
|
||||||
|
|
||||||
f=(FRAMEBUF *)ptrBuffer[iAsyncSel]; // setup prefetch addr
|
|
||||||
f->dwFrameCnt = MAXCACHEBLOCK+1;
|
|
||||||
f->dwBufLen = (MAXCACHEBLOCK+1)*iUsedBlockSize;
|
|
||||||
f->dwFrame = addr;
|
|
||||||
|
|
||||||
lLastAsyncAddr=addr; // store prefetch addr
|
|
||||||
|
|
||||||
if(pReadFunc(FALSE,f)!=SS_COMP) // start the async read
|
|
||||||
lLastAsyncAddr=0xFFFFFFFF; // -> if no success, no async prefetch buf available
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// here we do a sync read
|
|
||||||
|
|
||||||
iBufSel=0; // read in buf 0
|
|
||||||
|
|
||||||
f=(FRAMEBUF *)ptrBuffer[0];
|
|
||||||
f->dwFrame = addr;
|
|
||||||
|
|
||||||
pCurrReadBuf=pFirstReadBuf;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// if it's possible, we do a bigger read
|
|
||||||
|
|
||||||
if((addr+MAXCACHEBLOCK)<lMaxAddr)
|
|
||||||
{
|
|
||||||
f->dwFrameCnt = MAXCACHEBLOCK+1;
|
|
||||||
f->dwBufLen = (MAXCACHEBLOCK+1)*iUsedBlockSize;
|
|
||||||
lLastAddr = addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
f->dwFrameCnt = 1;
|
|
||||||
f->dwBufLen = iUsedBlockSize;
|
|
||||||
lLastAddr = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// start read, wait til finished
|
|
||||||
|
|
||||||
if(pReadFunc(TRUE,f)!=SS_COMP)
|
|
||||||
{
|
|
||||||
if(!bReadRetry(f)) return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(iUseDataCache && lLastAddr!=0xFFFFFFFF) // data cache used? and complete 64k block?
|
|
||||||
AddToDataCache(addr,pAsyncFirstReadBuf[0]); // -> add the complete data to cache
|
|
||||||
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// start additional async prefetch read, if it's ok
|
|
||||||
|
|
||||||
iTryAsync++;
|
|
||||||
if(iTryAsync>1) {iTryAsync=2;return TRUE;} // prefetches seems to be useless right now, so turn them off until next real read
|
|
||||||
|
|
||||||
addr+=MAXCACHEBLOCK+1; // prefetch addr
|
|
||||||
if(!((addr+MAXCACHEBLOCK)<lMaxAddr)) // not possible? do't do prefetch
|
|
||||||
{lLastAsyncAddr=0xFFFFFFFF;return TRUE;}
|
|
||||||
|
|
||||||
f=(FRAMEBUF *)ptrBuffer[1]; // setup prefetch into buf 1
|
|
||||||
f->dwFrameCnt = MAXCACHEBLOCK+1;
|
|
||||||
f->dwBufLen = (MAXCACHEBLOCK+1)*iUsedBlockSize;
|
|
||||||
f->dwFrame = addr;
|
|
||||||
|
|
||||||
lLastAsyncAddr= addr;
|
|
||||||
|
|
||||||
if(pReadFunc(FALSE,f)!=SS_COMP) // start the async prefetch
|
|
||||||
lLastAsyncAddr=0xFFFFFFFF;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// thread mode (caching 3)
|
|
||||||
// this mode helps with slower drives using the IOCTL
|
|
||||||
// interface (since that one seems to do always blocking
|
|
||||||
// reads, even when they are done overlapped).
|
|
||||||
// With ASPI, the thread mode performance will be more or less
|
|
||||||
// the same as with async caching mode 2...
|
|
||||||
// thread reading would be much more powerful, if the main
|
|
||||||
// emu would do:
|
|
||||||
// ...
|
|
||||||
// CDRreadTrack()
|
|
||||||
// ... do some other stuff here ...
|
|
||||||
// CDRgetBuffer()
|
|
||||||
// ...
|
|
||||||
// but lazy main emu coders seem to prefer:
|
|
||||||
// ...
|
|
||||||
// CDRreadTrack()
|
|
||||||
// CDRgetBuffer()
|
|
||||||
// ...
|
|
||||||
// so there is no time between the calls to do a good
|
|
||||||
// asynchronous read... sad, sad...
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// reading thread... sleeps until a new read is signaled
|
|
||||||
|
|
||||||
DWORD WINAPI READThread(LPVOID lpParameter)
|
|
||||||
{
|
|
||||||
FRAMEBUF * f;
|
|
||||||
|
|
||||||
while(WaitForMultipleObjects(2,hThreadEvent,FALSE, // wait until event to start (or event to end) get raised
|
|
||||||
INFINITE)==WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(hThreadMutex[0],INFINITE); // read mutex: nobody else is allowed to read now
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE); // variable access mutex: nobody else can change the vars now
|
|
||||||
ResetEvent(hThreadEvent[0]); // ok, kick event has been handled
|
|
||||||
SetEvent(hThreadEvent[2]); // set flag: we have started the read
|
|
||||||
|
|
||||||
lLastAsyncAddr = lNeededAddr; // setup read and vars
|
|
||||||
f=(FRAMEBUF *)ptrBuffer[!iBufSel]; // !iSel = async buffer
|
|
||||||
f->dwFrame = lNeededAddr;
|
|
||||||
f->dwFrameCnt = min((lMaxAddr-lNeededAddr+1),(MAXCACHEBLOCK+1));
|
|
||||||
f->dwBufLen = f->dwFrameCnt*iUsedBlockSize;
|
|
||||||
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // ok, vars have been changed, now that vars are again available for all
|
|
||||||
|
|
||||||
if(pReadFunc(TRUE,f)!=SS_COMP) // do a blocking (sync) read
|
|
||||||
{
|
|
||||||
bReadRetry(f); // mmm... if reading fails a number of times, we don't have a chance to return 'bad' to emu with tread reading... life is hard :)
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseMutex(hThreadMutex[0]); // ok, read has done
|
|
||||||
}
|
|
||||||
|
|
||||||
bThreadEnded=1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// emu says: we need data at given addr soon...
|
|
||||||
// so, if we don't have it in any buffer, we kick a read
|
|
||||||
// ... called on CDRreadTrack()
|
|
||||||
|
|
||||||
BOOL DoReadThread(unsigned long addr)
|
|
||||||
{
|
|
||||||
if(!hReadThread) return FALSE; // no thread, no fun
|
|
||||||
|
|
||||||
bDataCacheHit=FALSE; // init data cache hit flag (even if no cache is used...)
|
|
||||||
|
|
||||||
if(lLastAddr!=0xFFFFFFFF && // data is in curr data buffer?
|
|
||||||
addr>=lLastAddr &&
|
|
||||||
addr<=(lLastAddr+MAXCACHEBLOCK))
|
|
||||||
return TRUE; // -> fine
|
|
||||||
|
|
||||||
if(iUseDataCache && CheckDataCache(addr)) // data cache used and data is in cache? set read ptr, if yes
|
|
||||||
{bDataCacheHit=TRUE;return TRUE;} // -> and raise 'hit' flag, so we don't need to do anything in 'getbuffer'
|
|
||||||
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE); // wait to access 'buffer 1 vars'
|
|
||||||
|
|
||||||
if(lLastAsyncAddr!=0xFFFFFFFF && // data is (or will be soon if reading is going on in thread now) in async buffer?
|
|
||||||
addr>=lLastAsyncAddr &&
|
|
||||||
addr<=(lLastAsyncAddr+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // -> fine
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
// data is not in buf0 and not in buf1:
|
|
||||||
lNeededAddr=addr; // set needed adr (mutex is active, so it's safe to change that)
|
|
||||||
ResetEvent(hThreadEvent[2]); // reset "read has started" flag
|
|
||||||
SetEvent(hThreadEvent[0]); // set "start read" flag... the read will start reading soon after
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // done with var access
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// emu says: gimme ptr to needed data... this will
|
|
||||||
// automatically do an async data prefetch read as well
|
|
||||||
// ... called on CDRgetBuffer()
|
|
||||||
|
|
||||||
void GetREADThreadPtr(void)
|
|
||||||
{
|
|
||||||
unsigned long addr=lLastAccessedAddr;
|
|
||||||
|
|
||||||
if(bDataCacheHit) return; // if we had a data cache hit, the readbuf ptr is already fine, nothing else to do
|
|
||||||
|
|
||||||
if(lLastAddr!=0xFFFFFFFF && // data is in buffer 0?
|
|
||||||
addr>=lLastAddr &&
|
|
||||||
addr<=(lLastAddr+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
pCurrReadBuf=pAsyncFirstReadBuf[iBufSel]+ // -> ok, return curr data buffer ptr
|
|
||||||
((addr-lLastAddr)*iUsedBlockSize);
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitForSingleObject(hThreadEvent[2],INFINITE); // wait until reading has started (it will take a small time after the read start kick, so we have to go sure that it has _really_ started)
|
|
||||||
WaitForSingleObject(hThreadMutex[0],INFINITE); // wait until reading has finished
|
|
||||||
|
|
||||||
lLastAddr=lLastAsyncAddr; // move data to from async data to curr data buffer (by toggling iSel)
|
|
||||||
iBufSel=!iBufSel;
|
|
||||||
lLastAsyncAddr=0xFFFFFFFF; // nothing in async data buffer now
|
|
||||||
|
|
||||||
lNeededAddr=addr+MAXCACHEBLOCK+1; // prefetch read addr
|
|
||||||
ResetEvent(hThreadEvent[2]); // reset "read has started" flag
|
|
||||||
SetEvent(hThreadEvent[0]); // signal for start next read
|
|
||||||
ReleaseMutex(hThreadMutex[0]); // ok, now reading in buffer 1 can start
|
|
||||||
|
|
||||||
if(iUseDataCache) // data cache used? can be less then 64 kb with thread reading, but that doesn't matter here... will be either 64 k or (max-addr) sectors
|
|
||||||
AddToDataCache(lLastAddr,
|
|
||||||
pAsyncFirstReadBuf[iBufSel]); // -> add the complete data to cache
|
|
||||||
|
|
||||||
pCurrReadBuf=pAsyncFirstReadBuf[iBufSel]+ // -> return the curr data buffer ptr
|
|
||||||
((addr-lLastAddr)*iUsedBlockSize);
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// special thread mode (caching 4)
|
|
||||||
// this mode helps with certain drives
|
|
||||||
// basically it does the following:
|
|
||||||
// It has a queue for n prefetch reads. If the main emu is
|
|
||||||
// asking for an addr, the mode will check, if
|
|
||||||
// this addr is a) getting read right now, b) already
|
|
||||||
// in our 4 MB cache, c) already in the q.
|
|
||||||
// If no condition matches, it will add it in q...
|
|
||||||
// the same is done with the next n/2 addr blocks, so
|
|
||||||
// the q will keep the drive busy... also, if everything
|
|
||||||
// is cached (and the q is empty), we will add additional
|
|
||||||
// addresses to read, also to keep the drive busy, and to
|
|
||||||
// do the needed reading as soon as possible :)
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// reading thread...
|
|
||||||
|
|
||||||
DWORD WINAPI READThreadEx(LPVOID lpParameter)
|
|
||||||
{
|
|
||||||
FRAMEBUF * f;
|
|
||||||
|
|
||||||
while(WaitForMultipleObjects(2,hThreadEvent,FALSE, // wait until event to start (or event to end) get raised
|
|
||||||
INFINITE)==WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
//------------------------------------------------//
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE); // variable access mutex: nobody else can change the vars now
|
|
||||||
ResetEvent(hThreadEvent[0]); // ok, kick event has been handled
|
|
||||||
|
|
||||||
if(lAddrQ[iQPos]==0xFFFFFFFF) // nothing to do? strange :)
|
|
||||||
{ReleaseMutex(hThreadMutex[1]);break;}
|
|
||||||
|
|
||||||
f=(FRAMEBUF *)ptrBuffer[0];
|
|
||||||
lNeededAddr = lAddrQ[iQPos]; // store it in 'Neededaddr' for checks outside the thread
|
|
||||||
f->dwFrame = lNeededAddr;
|
|
||||||
f->dwFrameCnt = min((lMaxAddr-f->dwFrame+1),(MAXCACHEBLOCK+1));
|
|
||||||
f->dwBufLen = f->dwFrameCnt*iUsedBlockSize;
|
|
||||||
|
|
||||||
lAddrQ[iQPos++]=0xFFFFFFFF; // set this slot as 'done'
|
|
||||||
if(iQPos>=MAXQSIZE) iQPos=0; // amnd inc the head pos
|
|
||||||
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // ok, vars have been changed, now that vars are again available for all
|
|
||||||
//------------------------------------------------//
|
|
||||||
WaitForSingleObject(hThreadMutex[0],INFINITE); // read mutex: nobody else is allowed to read now
|
|
||||||
if(!iCDROK)
|
|
||||||
{
|
|
||||||
ReleaseMutex(hThreadMutex[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bCDDAPlay) // some cdda security...
|
|
||||||
{ // it should just prevent prefetch reads happening in cdda mode, if this one breaks a 'needed' read, we are lost...
|
|
||||||
lNeededAddr=0xFFFFFFFF; // so maybe we should remove this check? mmm, we will see
|
|
||||||
ReleaseMutex(hThreadMutex[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pReadFunc(TRUE,f)!=SS_COMP) // do a blocking (sync) read
|
|
||||||
{ // mmm... if reading fails a number of times, we don't have a chance to return 'bad' to emu with thread reading... life is hard :)
|
|
||||||
bReadRetry(f); // but at least our 'wait for data in cache' getptr will not wait forever (just returning wrong data, ehehe)
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseMutex(hThreadMutex[0]); // ok, read has done
|
|
||||||
//------------------------------------------------//
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE); // variable access mutex: nobody else can change the vars now
|
|
||||||
lNeededAddr=0xFFFFFFFF; // no read is now active
|
|
||||||
AddToDataCache(f->dwFrame,pFirstReadBuf); // add the complete data to cache
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // ok, vars have been changed, now that vars are again available for all
|
|
||||||
//------------------------------------------------//
|
|
||||||
if(WaitForSingleObject(hThreadEvent[0],0)!=WAIT_OBJECT_0)
|
|
||||||
Sleep(1); // if nobody has started a new kick, let's sleep awhile to give Windows more room to breath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bThreadEnded=1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// emu says: we need data at given addr soon...
|
|
||||||
// so, if we don't have it in any buffer, we kick a read
|
|
||||||
// ... called on CDRreadTrack()
|
|
||||||
|
|
||||||
//#define THREADEX_STRAIGHT
|
|
||||||
|
|
||||||
BOOL DoReadThreadEx(unsigned long addr)
|
|
||||||
{
|
|
||||||
int i,k,j=0;
|
|
||||||
|
|
||||||
if(!hReadThread) return FALSE; // no thread, no fun
|
|
||||||
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE); // wait for data access
|
|
||||||
|
|
||||||
//-----------------------------------------------------//
|
|
||||||
// straight reading try... should have been faster, but
|
|
||||||
// in 'real life' this approach keeps the cdrom drive
|
|
||||||
// spinning too much, giving other pc resources no room
|
|
||||||
// to breath... by increasing the thread 'Sleep' value
|
|
||||||
// the performance can get better, but then the annoying
|
|
||||||
// breaks we wanted to fight will show up again...
|
|
||||||
// so this type is disabled as long as nobody enables the
|
|
||||||
// define again :)
|
|
||||||
|
|
||||||
#ifdef THREADEX_STRAIGHT
|
|
||||||
|
|
||||||
if(addr>=lNeededAddr &&
|
|
||||||
addr<=(lNeededAddr+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
ReleaseMutex(hThreadMutex[1]);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(k=0;k<MAXQSIZE;k++) // loop max of prefetch blocks
|
|
||||||
{
|
|
||||||
for(i=0;i<MAXDATACACHE;i++) // loop whole cache
|
|
||||||
{
|
|
||||||
if(addr>=lDataCacheAddr[i] && // -> addr found?
|
|
||||||
addr<=(lDataCacheAddr[i]+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
if(k==0) iQLockPos=i; // -> if it's the current main addr, lock it, so no prefetch read overwrites its content
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i!=MAXDATACACHE) // found in data cache?
|
|
||||||
{addr=addr+MAXCACHEBLOCK+1;continue;} // -> do nothing with this addr, we have its content
|
|
||||||
else break; // here is the first unknown addr
|
|
||||||
}
|
|
||||||
|
|
||||||
if(addr>=lMaxAddr) // check, if addr too big
|
|
||||||
{
|
|
||||||
ReleaseMutex(hThreadMutex[1]);
|
|
||||||
if(k==0) return FALSE; // -> if it's the main addr, there is an error
|
|
||||||
return TRUE; // -> otherwise we can't simply cache that addr
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0;i<MAXQSIZE;i++) // loop q list
|
|
||||||
{
|
|
||||||
if(addr>=lAddrQ[i] && // -> addr will be read soon?
|
|
||||||
addr<=(lAddrQ[i]+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
addr=lAddrQ[i]; // --> take this aligned addr for new header
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0;i<MAXQSIZE;i++) // loop q list
|
|
||||||
{
|
|
||||||
lAddrQ[i]=addr;
|
|
||||||
addr=addr+MAXCACHEBLOCK+1;
|
|
||||||
if(addr>=lMaxAddr) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;i<MAXQSIZE;i++) // loop q list
|
|
||||||
{
|
|
||||||
lAddrQ[i]=0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
iQPos=0;
|
|
||||||
|
|
||||||
SetEvent(hThreadEvent[0]); // kick a read, if neccessary
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//-----------------------------------------------------//
|
|
||||||
// ok, here is the current ReadThreadEx mode: more
|
|
||||||
// complex, and it doesn't arrange the prefetch sectors
|
|
||||||
// as straight as the type above, but the final result is
|
|
||||||
// still smoother (no more pauses on the tested LG drive)
|
|
||||||
|
|
||||||
for(k=0;k<MAXQFETCH;k++) // loop max of prefetch blocks
|
|
||||||
{
|
|
||||||
if(addr>=lNeededAddr && // addr is getting read right now?
|
|
||||||
addr<=(lNeededAddr+MAXCACHEBLOCK)) // -> ok, we do nothing with it
|
|
||||||
{addr=addr+MAXCACHEBLOCK+1;continue;}
|
|
||||||
|
|
||||||
for(i=0;i<MAXDATACACHE;i++) // loop whole cache
|
|
||||||
{
|
|
||||||
if(addr>=lDataCacheAddr[i] && // -> addr found?
|
|
||||||
addr<=(lDataCacheAddr[i]+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
if(k==0) iQLockPos=i; // -> if it's the current main addr, lock it, so no other prefetch read overwrites its content
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i!=MAXDATACACHE) // found in data cache?
|
|
||||||
{addr=addr+MAXCACHEBLOCK+1;continue;} // -> do nothing with this addr, we have its content
|
|
||||||
|
|
||||||
for(i=0;i<MAXQSIZE;i++) // loop prefetch q list
|
|
||||||
{
|
|
||||||
if(addr>=lAddrQ[i] && // -> addr will be read soon?
|
|
||||||
addr<=(lAddrQ[i]+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
if(k==0 && i!=iQPos) // curr needed addr is not on top of the q?
|
|
||||||
{
|
|
||||||
addr=lAddrQ[i]; // -> get the addr (our main addr is in it, but that one is more aligned to prev reads)
|
|
||||||
for(i=0;i<MAXQSIZE;i++) lAddrQ[i]=0xFFFFFFFF; // -> clear whole q (we will fill the slots in that loop again)
|
|
||||||
i=MAXQSIZE; // -> sign for storing the addr in q
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i!=MAXQSIZE) // found in q?
|
|
||||||
{addr=addr+MAXCACHEBLOCK+1;continue;} // -> do nothing with this addr, we will have its content soon
|
|
||||||
|
|
||||||
// not in q or data cache?
|
|
||||||
if(k==0) lAddrQ[iQPos]=addr; // -> if it's the main addr, store it on top of list
|
|
||||||
else // -> if it's a prefetch addr, try to store it elsewhere at the end of the q
|
|
||||||
{
|
|
||||||
j=iQPos;
|
|
||||||
for(i=0;i<MAXQSIZE;i++)
|
|
||||||
{
|
|
||||||
if(lAddrQ[j]==0xFFFFFFFF) {lAddrQ[j]=addr;break;}
|
|
||||||
j++;if(j>=MAXQSIZE) j=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEvent(hThreadEvent[0]); // kick a read, if neccessary
|
|
||||||
addr=addr+MAXCACHEBLOCK+1; // next prefetch addr
|
|
||||||
if(addr>=lMaxAddr) break; // security, for detecting if we are at the end of cd
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------// ok, and here's something to keep the drive busy...
|
|
||||||
|
|
||||||
if(lAddrQ[iQPos]==0xFFFFFFFF && addr<lMaxAddr) // nothing in prefetch q?
|
|
||||||
{
|
|
||||||
iQIdle++; // count how many empty q's in-a-row are happening
|
|
||||||
if(iQIdle>10) // more then x times?
|
|
||||||
{
|
|
||||||
iQIdle=0;
|
|
||||||
lAddrQ[iQPos]=addr; // we add the farest prefetch addr
|
|
||||||
SetEvent(hThreadEvent[0]); // and do an additional kick
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else iQIdle=0; // not idling? ok
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ReleaseMutex(hThreadMutex[1]);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// emu says: gimme ptr to needed data... this will
|
|
||||||
// automatically do an async data prefetch read as well
|
|
||||||
// ... called on CDRgetBuffer()
|
|
||||||
|
|
||||||
void GetREADThreadExPtr(void)
|
|
||||||
{
|
|
||||||
unsigned long addr=lLastAccessedAddr;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(bThreadEnded) return; // main emu is already closing (thread is down)? bye
|
|
||||||
WaitForSingleObject(hThreadMutex[1],INFINITE); // wait for data access
|
|
||||||
if(CheckDataCache(addr)) // data now in cache?
|
|
||||||
{
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // -> ok, done
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ReleaseMutex(hThreadMutex[1]); // else try again (no sleep here, we are blocking everything anyway)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// simple data cache
|
|
||||||
|
|
||||||
void AllocDataCache(void)
|
|
||||||
{
|
|
||||||
bDataCacheHit=FALSE; // init thread cache hit flag
|
|
||||||
if(!iUseCaching) iUseDataCache=0; // security: no additinal data cache, if no caching active
|
|
||||||
if(iUseDataCache)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i=0;i<MAXDATACACHE;i++) // init all cache slots
|
|
||||||
{
|
|
||||||
lDataCacheAddr[i] = 0xFFFFFFFF;
|
|
||||||
pDataCacheBuf[i] = malloc(MAXCDBUFFER-FRAMEBUFEXTRA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void FreeDataCache(void)
|
|
||||||
{
|
|
||||||
if(iUseDataCache)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i=0;i<MAXDATACACHE;i++)
|
|
||||||
{
|
|
||||||
free(pDataCacheBuf[i]);
|
|
||||||
pDataCacheBuf[i]=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// easy data cache: stores data blocks
|
|
||||||
|
|
||||||
void AddToDataCache(unsigned long addr,unsigned char * pB)
|
|
||||||
{
|
|
||||||
static int iPos=0;
|
|
||||||
if(iPos==iQLockPos) // special thread mode lock?
|
|
||||||
{iPos++;if(iPos>=MAXDATACACHE) iPos=0;} // -> don't use that pos, use next one
|
|
||||||
lDataCacheAddr[iPos]=addr;
|
|
||||||
memcpy(pDataCacheBuf[iPos],pB,
|
|
||||||
MAXCDBUFFER-FRAMEBUFEXTRA);
|
|
||||||
iPos++; if(iPos>=MAXDATACACHE) iPos=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// easy data cache check: loop MAXDATACACHE blocks, set ptr if addr found
|
|
||||||
|
|
||||||
BOOL CheckDataCache(unsigned long addr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0;i<MAXDATACACHE;i++)
|
|
||||||
{
|
|
||||||
if(addr>=lDataCacheAddr[i] &&
|
|
||||||
addr<=(lDataCacheAddr[i]+MAXCACHEBLOCK))
|
|
||||||
{
|
|
||||||
pCurrReadBuf=pDataCacheBuf[i]+
|
|
||||||
((addr-lDataCacheAddr[i])*iUsedBlockSize);
|
|
||||||
if(ppfHead) CheckPPFCache(addr,pCurrReadBuf);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
read.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void CreateREADBufs(void);
|
|
||||||
void FreeREADBufs(void);
|
|
||||||
BOOL bReadRetry(FRAMEBUF * f);
|
|
||||||
BOOL DoReadAsync(unsigned long addr);
|
|
||||||
BOOL DoRead(unsigned long addr);
|
|
||||||
DWORD WINAPI READThread(LPVOID lpParameter);
|
|
||||||
BOOL DoReadThread(unsigned long addr);
|
|
||||||
void GetREADThreadPtr(void);
|
|
||||||
DWORD WINAPI READThreadEx(LPVOID lpParameter);
|
|
||||||
BOOL DoReadThreadEx(unsigned long addr);
|
|
||||||
void GetREADThreadExPtr(void);
|
|
||||||
void AllocDataCache(void);
|
|
||||||
void FreeDataCache(void);
|
|
||||||
void AddToDataCache(unsigned long addr,unsigned char * pB);
|
|
||||||
BOOL CheckDataCache(unsigned long addr);
|
|
|
@ -1,198 +0,0 @@
|
||||||
P.E.Op.S. PS2 CDVD emulation plugin
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The P.E.Op.S. PS2 CDVD plugin is based on the P.E.Op.S. PSX
|
|
||||||
CDR plugin which is based on Pete's CDR ASPI/IOCTL plugin
|
|
||||||
for Windows.
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Introduction - 19.11.2003
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
PS2 emulation is growing.
|
|
||||||
|
|
||||||
Oh, don't get me wrong, it will still need a lot of time until
|
|
||||||
you can really play your favourite PS2 games on the PC (ehe...
|
|
||||||
and I remember how I got flamed away nearly two years ago by
|
|
||||||
die-hard know-it-alls when I predicted that it will need at
|
|
||||||
least 'a couple of years' for 'playable' PS2 emulation).
|
|
||||||
|
|
||||||
But yeah, it is growing. Lotsa nice guys are spending their
|
|
||||||
free time coding on PCSX2, for example. One of them is Shadow...
|
|
||||||
and he never gets tired to ask me for some PS2 plugins, ehe.
|
|
||||||
|
|
||||||
Well, what to say? Last week I had some free time as well,
|
|
||||||
Shadow asked for a CDVD plugin, and so I got to work. I took
|
|
||||||
the P.E.Op.S. cdr sources, added the PCSX2 interface, changed
|
|
||||||
some lines of code, asked a few stupid questions (hi to
|
|
||||||
linuzappz), tested it with a few PS2 dvds and cds, and it was
|
|
||||||
done.
|
|
||||||
|
|
||||||
Of course it's not 100% complete. There are a few (but not
|
|
||||||
important) things missing, more cd/dvd modes have to get
|
|
||||||
investigated and added, etc. But basically I hope it will
|
|
||||||
work just fine with the current PCSX2 version. So go on,
|
|
||||||
and give it a try :)
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
|
|
||||||
* A cdrom/dvd drive (yeah, you need a dvd drive to play dvds...
|
|
||||||
no emails please telling me that your cd drive doesn't work
|
|
||||||
correctly with dvds).
|
|
||||||
* The ASPI layer with W9x/ME
|
|
||||||
* Nothing special with W2K/WXP
|
|
||||||
* Some PS2 cds/dvds.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Installation:
|
|
||||||
|
|
||||||
just copy the file cdvdPeops.dll into your PCSX2 \plugins
|
|
||||||
directory, that's all.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Configuration (similar to the P.E.Op.S. psx cdr plugin):
|
|
||||||
|
|
||||||
You HAVE TO configure the plugin before you use
|
|
||||||
it the first time. There are only a few options
|
|
||||||
available:
|
|
||||||
|
|
||||||
0) Interface
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
If you are using W9x/ME, you have to use the ASPI Interface.
|
|
||||||
If you are using NT/W2K/XP, you have the free choice:
|
|
||||||
ASPI (if it's installed), or IOCTL scsi commands.
|
|
||||||
|
|
||||||
1) Drive
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Well, that's self-explaining. Just select the drive
|
|
||||||
you want to use. "NONE" is NO drive... you have to
|
|
||||||
select a real one.
|
|
||||||
|
|
||||||
2.) Caching
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
To get more speed, there are five caching modes:
|
|
||||||
None, Read ahead, Async, Thread and Smooth.
|
|
||||||
|
|
||||||
- 'None' is the slowest mode, but it should work on
|
|
||||||
most drives.
|
|
||||||
- 'Read ahead' will read more sectors at once, speeding up
|
|
||||||
mdecs. There is a small chance that a few drives cannot
|
|
||||||
do it, so set it to 'None', if you are having troubles.
|
|
||||||
- The 'Async mode' will do read ahead and some additional
|
|
||||||
'intelligent' asynchronous reads... that mode is recommended
|
|
||||||
with the ASPI interface, it can squeeze some more speed
|
|
||||||
out of your drive :)
|
|
||||||
- The 'Thread mode' will speed up the IOCTL interfaces,
|
|
||||||
since that ones can't do real async reading. So, when
|
|
||||||
you are using W2K/XP, and you have no ASPI installed,
|
|
||||||
try this mode for best speed.
|
|
||||||
- Some drives will have speed problems reading ps2
|
|
||||||
cds/dvds, this caching mode will try to solve such issues.
|
|
||||||
|
|
||||||
|
|
||||||
Also available: an additional data cache option, which
|
|
||||||
will store up to 4 MBytes of already read sectors. This
|
|
||||||
can speed up certain games, which are re-reading the
|
|
||||||
same range of sectors again and again.
|
|
||||||
|
|
||||||
|
|
||||||
3.) Speed limitation
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
Some drives will work better (less noisy and smoother)
|
|
||||||
if you limit the drive speed. Not all drives are supporting
|
|
||||||
the "set speed" command I am using, though.
|
|
||||||
If your drive doesn't support it, a message will be displayed
|
|
||||||
on startup. There are some tools in the net which will
|
|
||||||
offer the same function, prolly for a wider range of drives,
|
|
||||||
so you can also try one of them, if the plugin speed limit fails.
|
|
||||||
|
|
||||||
|
|
||||||
4.) Don't wait til drive is ready
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
By default my plugin is asking the cd/dvd drive on startup,
|
|
||||||
if its state is ready (that means: a cd is inserted and the
|
|
||||||
drive can start reading).
|
|
||||||
A few drives will not answer that question (bah, bah, bah),
|
|
||||||
and the screen will stay black... forever :)
|
|
||||||
If you are encoutering that problem, you can turn on the
|
|
||||||
"Don't wait..." option, but be warned: it can cause problems
|
|
||||||
(blue screens, for example) if the plugin starts reading and
|
|
||||||
there is a problem with the drive...
|
|
||||||
|
|
||||||
|
|
||||||
5.) Check drive tray state
|
|
||||||
-----------------------------------------------
|
|
||||||
PCSX2 may ask the plugin if the tray is open or closed. If
|
|
||||||
this option is turned off, the plugion always will respond
|
|
||||||
"closed". If this option is enabled, the plugin will try
|
|
||||||
to ask the drive for the tray state. Since I couldn't test
|
|
||||||
this option yet, I suggest to leave it off (and honestly,
|
|
||||||
are you able to run a multi-dvd game which needs disc
|
|
||||||
changing right now in PCSX2?) :)
|
|
||||||
|
|
||||||
|
|
||||||
6.) Try again on reading error
|
|
||||||
-----------------------------------------------
|
|
||||||
It might happen that your drive can't read a certain sector at
|
|
||||||
the first time, if your cd/dvd is scratched. Therefore I've added
|
|
||||||
that option, by activating it you can tell the plugin to try it
|
|
||||||
up to 10 times again before reporting the read error to the
|
|
||||||
main emu.
|
|
||||||
If you want, you can also activate some error message box,
|
|
||||||
if a sector is not readable (just to inform you something is
|
|
||||||
going wrong).
|
|
||||||
|
|
||||||
|
|
||||||
7.) Use PPF patches (not available yet)
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
- TODO :)
|
|
||||||
|
|
||||||
|
|
||||||
8.) Subchannel reading (not available yet)
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
- MAYBE TODO :)
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Conclusion:
|
|
||||||
|
|
||||||
You never ever can escape your Shadow ;)
|
|
||||||
|
|
||||||
For version infos read the "version.txt" file.
|
|
||||||
|
|
||||||
And, peops, have fun!
|
|
||||||
|
|
||||||
Pete Bernert
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
P.E.Op.S. page on sourceforge: https://sourceforge.net/projects/peops/
|
|
||||||
|
|
||||||
P.E.Op.S. developer:
|
|
||||||
|
|
||||||
Pete Bernert http://www.pbernert.com
|
|
||||||
Lewpy http://lewpy.psxemu.com/
|
|
||||||
lu_zero http://brsk.virtualave.net/lu_zero/
|
|
||||||
linuzappz http://www.pcsx.net
|
|
||||||
Darko Matesic http://mrdario.tripod.com
|
|
||||||
syo http://www.geocities.co.jp/SiliconValley-Bay/2072/
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Disclaimer/Licence:
|
|
||||||
|
|
||||||
This plugin is under GPL... check out the license.txt file in the /src
|
|
||||||
directory for details.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
|
|
@ -1,56 +0,0 @@
|
||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Developer Studio generated include file.
|
|
||||||
// Used by cdvdPeops.rc
|
|
||||||
//
|
|
||||||
#define IDD_CONFIG 101
|
|
||||||
#define IDD_ABOUT 102
|
|
||||||
#define IDD_SUB 104
|
|
||||||
#define IDC_DRIVE 1000
|
|
||||||
#define IDC_RTYPE 1001
|
|
||||||
#define IDC_AUTO 1002
|
|
||||||
#define IDC_CACHE 1003
|
|
||||||
#define IDC_SPEEDLIMIT 1004
|
|
||||||
#define IDC_SPEED 1005
|
|
||||||
#define IDC_NOWAIT 1006
|
|
||||||
#define IDC_RETRY 1007
|
|
||||||
#define IDC_SHOWREADERR 1008
|
|
||||||
#define IDC_TRYAGAIN 1009
|
|
||||||
#define IDC_USEPPF 1010
|
|
||||||
#define IDC_PPFFILE 1011
|
|
||||||
#define IDC_CHOOSEFILE 1012
|
|
||||||
#define IDC_IMODE 1013
|
|
||||||
#define IDC_RAWTXT 1014
|
|
||||||
#define IDC_TRAYSTATE 1014
|
|
||||||
#define IDC_SUBCHAN0 1015
|
|
||||||
#define IDC_SUBCHAN1 1016
|
|
||||||
#define IDC_DATACACHE 1016
|
|
||||||
#define IDC_SUBCHAN2 1017
|
|
||||||
#define IDC_SUBFILE 1018
|
|
||||||
#define IDC_CHOOSESUBF 1019
|
|
||||||
#define IDC_CREATESUB 1020
|
|
||||||
#define IDC_CHOOSEOUTF 1020
|
|
||||||
#define IDC_SUBTYPE 1021
|
|
||||||
#define IDC_SUBSTATIC 1023
|
|
||||||
#define IDC_WAITSTATIC 1024
|
|
||||||
#define IDC_SUBFRAME 1026
|
|
||||||
#define IDC_SUBOUTSTATIC 1027
|
|
||||||
#define IDC_SUBFILEEDIT 1028
|
|
||||||
#define IDC_SUBOUTSTATIC2 1029
|
|
||||||
#define IDC_OUTFILEEDIT 1030
|
|
||||||
#define IDC_SUBMODE1 1031
|
|
||||||
#define IDC_SUBMODE2 1032
|
|
||||||
#define IDC_SUBOUTSTATIC3 1033
|
|
||||||
#define IDC_SUBFILL 1034
|
|
||||||
#define IDC_SUBOUTSTATIC4 1035
|
|
||||||
#define IDC_SFSTATIC 1035
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 107
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1036
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,55 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
scsi.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/28 - linuzappz
|
|
||||||
// - added GetSCSIStatus
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
int GetSCSIDevice(int iA,int iT,int iL);
|
|
||||||
int GetSCSIStatus(int iA,int iT,int iL);
|
|
||||||
DWORD GetSCSITOC(LPTOC toc);
|
|
||||||
int GetSCSICDDrives(char * pDList);
|
|
||||||
DWORD PlaySCSIAudio(unsigned long start,unsigned long len);
|
|
||||||
unsigned char * GetSCSIAudioSub(void);
|
|
||||||
BOOL TestSCSIUnitReady(void);
|
|
||||||
DWORD SetSCSISpeed(DWORD dwSpeed);
|
|
||||||
DWORD ReadSCSI_BE(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD ReadSCSI_BE_Sub(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD ReadSCSI_BE_Sub_1(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD InitSCSI_28_1(void);
|
|
||||||
DWORD InitSCSI_28_2(void);
|
|
||||||
DWORD DeInitSCSI_28(void);
|
|
||||||
DWORD ReadSCSI_28(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD ReadSCSI_28_Sub(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD InitSCSI_28_2048(void);
|
|
||||||
DWORD ReadSCSI_28_2048(BOOL bWait,FRAMEBUF * f);
|
|
||||||
DWORD ReadSCSI_28_2048_Ex(BOOL bWait,FRAMEBUF * f);
|
|
||||||
int ReadSub_BE_2(unsigned long addr,unsigned char * pBuf,int iNum);
|
|
||||||
int ReadSub_BE_2_1(unsigned long addr,unsigned char * pBuf,int iNum);
|
|
||||||
int ReadSub_D8(unsigned long addr,unsigned char * pBuf,int iNum);
|
|
||||||
void DecodeSub_BE_2_1(unsigned char * pBuf);
|
|
||||||
DWORD CheckSCSIReadMode(void);
|
|
||||||
DWORD ReadSCSI_Dummy(BOOL bWait,FRAMEBUF * f);
|
|
||||||
|
|
|
@ -1,579 +0,0 @@
|
||||||
//***************************************************************************
|
|
||||||
//
|
|
||||||
// Name: SCSIDEFS.H
|
|
||||||
//
|
|
||||||
// Description: SCSI definitions ('C' Language)
|
|
||||||
//
|
|
||||||
//***************************************************************************
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% TARGET STATUS VALUES %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define STATUS_GOOD 0x00 // Status Good
|
|
||||||
#define STATUS_CHKCOND 0x02 // Check Condition
|
|
||||||
#define STATUS_CONDMET 0x04 // Condition Met
|
|
||||||
#define STATUS_BUSY 0x08 // Busy
|
|
||||||
#define STATUS_INTERM 0x10 // Intermediate
|
|
||||||
#define STATUS_INTCDMET 0x14 // Intermediate-condition met
|
|
||||||
#define STATUS_RESCONF 0x18 // Reservation conflict
|
|
||||||
#define STATUS_COMTERM 0x22 // Command Terminated
|
|
||||||
#define STATUS_QFULL 0x28 // Queue full
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% SCSI MISCELLANEOUS EQUATES %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define MAXLUN 7 // Maximum Logical Unit Id
|
|
||||||
#define MAXTARG 7 // Maximum Target Id
|
|
||||||
#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs
|
|
||||||
#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's
|
|
||||||
|
|
||||||
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
|
||||||
//
|
|
||||||
// %%% SCSI COMMAND OPCODES %%%
|
|
||||||
//
|
|
||||||
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands for all Device Types %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional)
|
|
||||||
#define SCSI_COMPARE 0x39 // Compare (O)
|
|
||||||
#define SCSI_COPY 0x18 // Copy (O)
|
|
||||||
#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O)
|
|
||||||
#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY)
|
|
||||||
#define SCSI_LOG_SELECT 0x4C // Log Select (O)
|
|
||||||
#define SCSI_LOG_SENSE 0x4D // Log Sense (O)
|
|
||||||
#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific)
|
|
||||||
#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific)
|
|
||||||
#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific)
|
|
||||||
#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific)
|
|
||||||
#define SCSI_READ_BUFF 0x3C // Read Buffer (O)
|
|
||||||
#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY)
|
|
||||||
#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O)
|
|
||||||
#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY)
|
|
||||||
#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Direct Access Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_COMPARE 0x39 // Compare (O)
|
|
||||||
#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY)
|
|
||||||
#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O)
|
|
||||||
#define SCSI_PREFETCH 0x34 // Prefetch (O)
|
|
||||||
#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O)
|
|
||||||
#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY)
|
|
||||||
#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY)
|
|
||||||
#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY)
|
|
||||||
#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O)
|
|
||||||
#define SCSI_READ_LONG 0x3E // Read Long (O)
|
|
||||||
#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O)
|
|
||||||
#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O)
|
|
||||||
#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY)
|
|
||||||
#define SCSI_REZERO 0x01 // Rezero Unit (O)
|
|
||||||
#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O)
|
|
||||||
#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O)
|
|
||||||
#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O)
|
|
||||||
#define SCSI_SEEK6 0x0B // Seek 6-Byte (O)
|
|
||||||
#define SCSI_SEEK10 0x2B // Seek 10-Byte (O)
|
|
||||||
#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY)
|
|
||||||
#define SCSI_SET_LIMIT 0x33 // Set Limits (O)
|
|
||||||
#define SCSI_START_STP 0x1B // Start/Stop Unit (O)
|
|
||||||
#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O)
|
|
||||||
#define SCSI_VERIFY 0x2F // Verify (O)
|
|
||||||
#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY)
|
|
||||||
#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY)
|
|
||||||
#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O)
|
|
||||||
#define SCSI_WRITE_LONG 0x3F // Write Long (O)
|
|
||||||
#define SCSI_WRITE_SAME 0x41 // Write Same (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Sequential Access Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_ERASE 0x19 // Erase (MANDATORY)
|
|
||||||
#define SCSI_LOAD_UN 0x1B // Load/Unload (O)
|
|
||||||
#define SCSI_LOCATE 0x2B // Locate (O)
|
|
||||||
#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY)
|
|
||||||
#define SCSI_READ_POS 0x34 // Read Position (O)
|
|
||||||
#define SCSI_READ_REV 0x0F // Read Reverse (O)
|
|
||||||
#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O)
|
|
||||||
#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY)
|
|
||||||
#define SCSI_REWIND 0x01 // Rewind (MANDATORY)
|
|
||||||
#define SCSI_SPACE 0x11 // Space (MANDATORY)
|
|
||||||
#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O)
|
|
||||||
#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Printer Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_PRINT 0x0A // Print (MANDATORY)
|
|
||||||
#define SCSI_SLEW_PNT 0x0B // Slew and Print (O)
|
|
||||||
#define SCSI_STOP_PNT 0x1B // Stop Print (O)
|
|
||||||
#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Processor Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_RECEIVE 0x08 // Receive (O)
|
|
||||||
#define SCSI_SEND 0x0A // Send (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Write-Once Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O)
|
|
||||||
#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O)
|
|
||||||
#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O)
|
|
||||||
#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O)
|
|
||||||
#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O)
|
|
||||||
#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O)
|
|
||||||
#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O)
|
|
||||||
#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O)
|
|
||||||
#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O)
|
|
||||||
#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O)
|
|
||||||
#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O)
|
|
||||||
#define SCSI_WRITE12 0xAA // Write 12-Byte (O)
|
|
||||||
#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O)
|
|
||||||
#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to CD-ROM Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O)
|
|
||||||
#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O)
|
|
||||||
#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O)
|
|
||||||
#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O)
|
|
||||||
#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O)
|
|
||||||
#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O)
|
|
||||||
#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY)
|
|
||||||
#define SCSI_READHEADER 0x44 // Read Header (O)
|
|
||||||
#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O)
|
|
||||||
#define SCSI_READ_TOC 0x43 // Read TOC (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Scanner Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O)
|
|
||||||
#define SCSI_GETWINDOW 0x25 // Get Window (O)
|
|
||||||
#define SCSI_OBJECTPOS 0x31 // Object Postion (O)
|
|
||||||
#define SCSI_SCAN 0x1B // Scan (O)
|
|
||||||
#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Optical Memory Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_UpdateBlk 0x3D // Update Block (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Medium Changer Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O)
|
|
||||||
#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O)
|
|
||||||
#define SCSI_POSTOELEM 0x2B // Position to Element (O)
|
|
||||||
#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O)
|
|
||||||
#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O)
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Commands Unique to Communication Devices %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY)
|
|
||||||
#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O)
|
|
||||||
#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O)
|
|
||||||
#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY)
|
|
||||||
#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O)
|
|
||||||
#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O)
|
|
||||||
|
|
||||||
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
|
||||||
//
|
|
||||||
// %%% END OF SCSI COMMAND OPCODES %%%
|
|
||||||
//
|
|
||||||
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% Request Sense Data Format %%%
|
|
||||||
//***************************************************************************
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
BYTE ErrorCode; // Error Code (70H or 71H)
|
|
||||||
BYTE SegmentNum; // Number of current segment descriptor
|
|
||||||
BYTE SenseKey; // Sense Key(See bit definitions too)
|
|
||||||
BYTE InfoByte0; // Information MSB
|
|
||||||
BYTE InfoByte1; // Information MID
|
|
||||||
BYTE InfoByte2; // Information MID
|
|
||||||
BYTE InfoByte3; // Information LSB
|
|
||||||
BYTE AddSenLen; // Additional Sense Length
|
|
||||||
BYTE ComSpecInf0; // Command Specific Information MSB
|
|
||||||
BYTE ComSpecInf1; // Command Specific Information MID
|
|
||||||
BYTE ComSpecInf2; // Command Specific Information MID
|
|
||||||
BYTE ComSpecInf3; // Command Specific Information LSB
|
|
||||||
BYTE AddSenseCode; // Additional Sense Code
|
|
||||||
BYTE AddSenQual; // Additional Sense Code Qualifier
|
|
||||||
BYTE FieldRepUCode; // Field Replaceable Unit Code
|
|
||||||
BYTE SenKeySpec15; // Sense Key Specific 15th byte
|
|
||||||
BYTE SenKeySpec16; // Sense Key Specific 16th byte
|
|
||||||
BYTE SenKeySpec17; // Sense Key Specific 17th byte
|
|
||||||
BYTE AddSenseBytes; // Additional Sense Bytes
|
|
||||||
|
|
||||||
} SENSE_DATA_FMT;
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% REQUEST SENSE ERROR CODE %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SERROR_CURRENT 0x70 // Current Errors
|
|
||||||
#define SERROR_DEFERED 0x71 // Deferred Errors
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% REQUEST SENSE BIT DEFINITIONS %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define SENSE_VALID 0x80 // Byte 0 Bit 7
|
|
||||||
#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7
|
|
||||||
#define SENSE_EOM 0x40 // Byte 2 Bit 6
|
|
||||||
#define SENSE_ILI 0x20 // Byte 2 Bit 5
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define KEY_NOSENSE 0x00 // No Sense
|
|
||||||
#define KEY_RECERROR 0x01 // Recovered Error
|
|
||||||
#define KEY_NOTREADY 0x02 // Not Ready
|
|
||||||
#define KEY_MEDIUMERR 0x03 // Medium Error
|
|
||||||
#define KEY_HARDERROR 0x04 // Hardware Error
|
|
||||||
#define KEY_ILLGLREQ 0x05 // Illegal Request
|
|
||||||
#define KEY_UNITATT 0x06 // Unit Attention
|
|
||||||
#define KEY_DATAPROT 0x07 // Data Protect
|
|
||||||
#define KEY_BLANKCHK 0x08 // Blank Check
|
|
||||||
#define KEY_VENDSPEC 0x09 // Vendor Specific
|
|
||||||
#define KEY_COPYABORT 0x0A // Copy Abort
|
|
||||||
#define KEY_EQUAL 0x0C // Equal (Search)
|
|
||||||
#define KEY_VOLOVRFLW 0x0D // Volume Overflow
|
|
||||||
#define KEY_MISCOMP 0x0E // Miscompare (Search)
|
|
||||||
#define KEY_RESERVED 0x0F // Reserved
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define DTYPE_DASD 0x00 // Disk Device
|
|
||||||
#define DTYPE_SEQD 0x01 // Tape Device
|
|
||||||
#define DTYPE_PRNT 0x02 // Printer
|
|
||||||
#define DTYPE_PROC 0x03 // Processor
|
|
||||||
#define DTYPE_WORM 0x04 // Write-once read-multiple
|
|
||||||
#define DTYPE_CROM 0x05 // CD-ROM device
|
|
||||||
#define DTYPE_CDROM 0x05 // CD-ROM device
|
|
||||||
#define DTYPE_SCAN 0x06 // Scanner device
|
|
||||||
#define DTYPE_OPTI 0x07 // Optical memory device
|
|
||||||
#define DTYPE_JUKE 0x08 // Medium Changer device
|
|
||||||
#define DTYPE_COMM 0x09 // Communications device
|
|
||||||
#define DTYPE_RESL 0x0A // Reserved (low)
|
|
||||||
#define DTYPE_RESH 0x1E // Reserved (high)
|
|
||||||
#define DTYPE_UNKNOWN 0x1F // Unknown or no device type
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
// %%% ANSI APPROVED VERSION DEFINITIONS %%%
|
|
||||||
//***************************************************************************
|
|
||||||
#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand
|
|
||||||
#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1)
|
|
||||||
#define ANSI_SCSI2 0x2 // Device complies to SCSI-2
|
|
||||||
#define ANSI_RESLO 0x3 // Reserved (low)
|
|
||||||
#define ANSI_RESHI 0x7 // Reserved (high)
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR ScsiStatus;
|
|
||||||
UCHAR PathId;
|
|
||||||
UCHAR TargetId;
|
|
||||||
UCHAR Lun;
|
|
||||||
UCHAR CdbLength;
|
|
||||||
UCHAR SenseInfoLength;
|
|
||||||
UCHAR DataIn;
|
|
||||||
ULONG DataTransferLength;
|
|
||||||
ULONG TimeOutValue;
|
|
||||||
ULONG DataBufferOffset;
|
|
||||||
ULONG SenseInfoOffset;
|
|
||||||
UCHAR Cdb[16];
|
|
||||||
} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR ScsiStatus;
|
|
||||||
UCHAR PathId;
|
|
||||||
UCHAR TargetId;
|
|
||||||
UCHAR Lun;
|
|
||||||
UCHAR CdbLength;
|
|
||||||
UCHAR SenseInfoLength;
|
|
||||||
UCHAR DataIn;
|
|
||||||
ULONG DataTransferLength;
|
|
||||||
ULONG TimeOutValue;
|
|
||||||
PVOID DataBuffer;
|
|
||||||
ULONG SenseInfoOffset;
|
|
||||||
UCHAR Cdb[16];
|
|
||||||
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
SCSI_PASS_THROUGH spt;
|
|
||||||
ULONG Filler;
|
|
||||||
UCHAR ucSenseBuf[32];
|
|
||||||
UCHAR ucDataBuf[512];
|
|
||||||
} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
SCSI_PASS_THROUGH_DIRECT spt;
|
|
||||||
ULONG Filler;
|
|
||||||
UCHAR ucSenseBuf[32];
|
|
||||||
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UCHAR NumberOfLogicalUnits;
|
|
||||||
UCHAR InitiatorBusId;
|
|
||||||
ULONG InquiryDataOffset;
|
|
||||||
} SCSI_BUS_DATA, *PSCSI_BUS_DATA;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UCHAR NumberOfBusses;
|
|
||||||
SCSI_BUS_DATA BusData[1];
|
|
||||||
} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UCHAR PathId;
|
|
||||||
UCHAR TargetId;
|
|
||||||
UCHAR Lun;
|
|
||||||
BOOLEAN DeviceClaimed;
|
|
||||||
ULONG InquiryDataLength;
|
|
||||||
ULONG NextInquiryDataOffset;
|
|
||||||
UCHAR InquiryData[1];
|
|
||||||
} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ULONG Length;
|
|
||||||
UCHAR PortNumber;
|
|
||||||
UCHAR PathId;
|
|
||||||
UCHAR TargetId;
|
|
||||||
UCHAR Lun;
|
|
||||||
} SCSI_ADDRESS, *PSCSI_ADDRESS;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* method codes
|
|
||||||
*/
|
|
||||||
#define METHOD_BUFFERED 0
|
|
||||||
#define METHOD_IN_DIRECT 1
|
|
||||||
#define METHOD_OUT_DIRECT 2
|
|
||||||
#define METHOD_NEITHER 3
|
|
||||||
|
|
||||||
/*
|
|
||||||
* file access values
|
|
||||||
*/
|
|
||||||
#define FILE_ANY_ACCESS 0
|
|
||||||
#define FILE_READ_ACCESS (0x0001)
|
|
||||||
#define FILE_WRITE_ACCESS (0x0002)
|
|
||||||
|
|
||||||
|
|
||||||
#define IOCTL_SCSI_BASE 0x00000004
|
|
||||||
|
|
||||||
/*
|
|
||||||
* constants for DataIn member of SCSI_PASS_THROUGH* structures
|
|
||||||
*/
|
|
||||||
#define SCSI_IOCTL_DATA_OUT 0
|
|
||||||
#define SCSI_IOCTL_DATA_IN 1
|
|
||||||
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Standard IOCTL define
|
|
||||||
*/
|
|
||||||
#define CTL_CODE( DevType, Function, Method, Access ) ( \
|
|
||||||
((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define IOCTL_SCSI_PASS_THROUGH CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
|
||||||
#define IOCTL_SCSI_MINIPORT CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
|
||||||
#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
||||||
#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
||||||
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
|
||||||
#define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
|
||||||
|
|
||||||
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
|
|
||||||
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
|
|
||||||
|
|
||||||
#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
|
|
||||||
#define FILE_DEVICE_CD_ROM 0x00000002
|
|
||||||
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
|
|
||||||
#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
|
|
||||||
typedef struct _CDROM_SEEK_AUDIO_MSF {
|
|
||||||
UCHAR M;
|
|
||||||
UCHAR S;
|
|
||||||
UCHAR F;
|
|
||||||
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;
|
|
||||||
|
|
||||||
//
|
|
||||||
// CD ROM Sub-Q Channel Data Format
|
|
||||||
//
|
|
||||||
|
|
||||||
#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00
|
|
||||||
#define IOCTL_CDROM_CURRENT_POSITION 0x01
|
|
||||||
#define IOCTL_CDROM_MEDIA_CATALOG 0x02
|
|
||||||
#define IOCTL_CDROM_TRACK_ISRC 0x03
|
|
||||||
|
|
||||||
typedef struct _CDROM_SUB_Q_DATA_FORMAT {
|
|
||||||
UCHAR Format;
|
|
||||||
UCHAR Track;
|
|
||||||
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;
|
|
||||||
|
|
||||||
typedef struct _SUB_Q_HEADER {
|
|
||||||
UCHAR Reserved;
|
|
||||||
UCHAR AudioStatus;
|
|
||||||
UCHAR DataLength[2];
|
|
||||||
} SUB_Q_HEADER, *PSUB_Q_HEADER;
|
|
||||||
|
|
||||||
typedef struct _SUB_Q_CURRENT_POSITION {
|
|
||||||
SUB_Q_HEADER Header;
|
|
||||||
UCHAR FormatCode;
|
|
||||||
UCHAR Control : 4;
|
|
||||||
UCHAR ADR : 4;
|
|
||||||
UCHAR TrackNumber;
|
|
||||||
UCHAR IndexNumber;
|
|
||||||
UCHAR AbsoluteAddress[4];
|
|
||||||
UCHAR TrackRelativeAddress[4];
|
|
||||||
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;
|
|
||||||
|
|
||||||
typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
|
|
||||||
SUB_Q_HEADER Header;
|
|
||||||
UCHAR FormatCode;
|
|
||||||
UCHAR Reserved[3];
|
|
||||||
UCHAR Reserved1 : 7;
|
|
||||||
UCHAR Mcval : 1;
|
|
||||||
UCHAR MediaCatalog[15];
|
|
||||||
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;
|
|
||||||
|
|
||||||
typedef struct _SUB_Q_TRACK_ISRC {
|
|
||||||
SUB_Q_HEADER Header;
|
|
||||||
UCHAR FormatCode;
|
|
||||||
UCHAR Reserved0;
|
|
||||||
UCHAR Track;
|
|
||||||
UCHAR Reserved1;
|
|
||||||
UCHAR Reserved2 : 7;
|
|
||||||
UCHAR Tcval : 1;
|
|
||||||
UCHAR TrackIsrc[15];
|
|
||||||
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;
|
|
||||||
|
|
||||||
typedef union _SUB_Q_CHANNEL_DATA {
|
|
||||||
SUB_Q_CURRENT_POSITION CurrentPosition;
|
|
||||||
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog;
|
|
||||||
SUB_Q_TRACK_ISRC TrackIsrc;
|
|
||||||
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;
|
|
||||||
|
|
||||||
|
|
||||||
// IOCTL_DISK_SET_CACHE allows the caller to get or set the state of the disk
|
|
||||||
// read/write caches.
|
|
||||||
//
|
|
||||||
// If the structure is provided as the input buffer for the ioctl the read &
|
|
||||||
// write caches will be enabled or disabled depending on the parameters
|
|
||||||
// provided.
|
|
||||||
//
|
|
||||||
// If the structure is provided as an output buffer for the ioctl the state
|
|
||||||
// of the read & write caches will be returned. If both input and outut buffers
|
|
||||||
// are provided the output buffer will contain the cache state BEFORE any
|
|
||||||
// changes are made
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
EqualPriority,
|
|
||||||
KeepPrefetchedData,
|
|
||||||
KeepReadData
|
|
||||||
} DISK_CACHE_RETENTION_PRIORITY;
|
|
||||||
|
|
||||||
#define FILE_DEVICE_DISK 0x00000007
|
|
||||||
#define IOCTL_DISK_BASE FILE_DEVICE_DISK
|
|
||||||
#define IOCTL_DISK_GET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0035, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_DISK_SET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0036, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
|
||||||
|
|
||||||
typedef struct _DISK_CACHE_INFORMATION {
|
|
||||||
|
|
||||||
//
|
|
||||||
// on return indicates that the device is capable of saving any parameters
|
|
||||||
// in non-volatile storage. On send indicates that the device should
|
|
||||||
// save the state in non-volatile storage.
|
|
||||||
//
|
|
||||||
|
|
||||||
BOOLEAN ParametersSavable;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Indicates whether the write and read caches are enabled.
|
|
||||||
//
|
|
||||||
|
|
||||||
BOOLEAN ReadCacheEnabled;
|
|
||||||
BOOLEAN WriteCacheEnabled;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Controls the likelyhood of data remaining in the cache depending on how
|
|
||||||
// it got there. Data cached from a READ or WRITE operation may be given
|
|
||||||
// higher, lower or equal priority to data entered into the cache for other
|
|
||||||
// means (like prefetch)
|
|
||||||
//
|
|
||||||
|
|
||||||
DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority;
|
|
||||||
DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Requests for a larger number of blocks than this may have prefetching
|
|
||||||
// disabled. If this value is set to 0 prefetch will be disabled.
|
|
||||||
//
|
|
||||||
|
|
||||||
USHORT DisablePrefetchTransferLength;
|
|
||||||
|
|
||||||
//
|
|
||||||
// If TRUE then ScalarPrefetch (below) will be valid. If FALSE then
|
|
||||||
// the minimum and maximum values should be treated as a block count
|
|
||||||
// (BlockPrefetch)
|
|
||||||
//
|
|
||||||
|
|
||||||
BOOLEAN PrefetchScalar;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Contains the minimum and maximum amount of data which will be
|
|
||||||
// will be prefetched into the cache on a disk operation. This value
|
|
||||||
// may either be a scalar multiplier of the transfer length of the request,
|
|
||||||
// or an abolute number of disk blocks. PrefetchScalar (above) indicates
|
|
||||||
// which interpretation is used.
|
|
||||||
//
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
USHORT Minimum;
|
|
||||||
USHORT Maximum;
|
|
||||||
|
|
||||||
//
|
|
||||||
// The maximum number of blocks which will be prefetched - useful
|
|
||||||
// with the scalar limits to set definite upper limits.
|
|
||||||
//
|
|
||||||
|
|
||||||
USHORT MaximumBlocks;
|
|
||||||
} ScalarPrefetch;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
USHORT Minimum;
|
|
||||||
USHORT Maximum;
|
|
||||||
} BlockPrefetch;
|
|
||||||
};
|
|
||||||
|
|
||||||
} DISK_CACHE_INFORMATION, *PDISK_CACHE_INFORMATION;
|
|
||||||
|
|
|
@ -1,321 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
sub.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_SUB
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/* TODO (#1#): SUB CHANNEL STUFF */
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
unsigned char * pCurrSubBuf=NULL; // ptr to emu sub data (or NULL)
|
|
||||||
int iUseSubReading=0; // subdata support (by file or directly)
|
|
||||||
char szSUBF[260]; // sub file name
|
|
||||||
SUB_CACHE * subCache=NULL; // cache memory
|
|
||||||
SUB_DATA * subHead=NULL;
|
|
||||||
int iSUBNum=0; // number of subdata cached
|
|
||||||
unsigned char SubCData[96]; // global data subc buffer
|
|
||||||
unsigned char SubAData[96]; // global audio subc buffer
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void BuildSUBCache(void)
|
|
||||||
{
|
|
||||||
FILE * subfile;
|
|
||||||
unsigned char buffer[16], * p;
|
|
||||||
SUB_DATA * plast=NULL,* px;
|
|
||||||
|
|
||||||
if(iUseSubReading) // some subreading wanted?
|
|
||||||
{
|
|
||||||
if(iUseSubReading==1) iUseCaching=0; // -> direct read? no caching done, only 1 sector reads
|
|
||||||
memset(SubCData,0,96); // -> init subc
|
|
||||||
pCurrSubBuf=SubCData; // -> set global ptr
|
|
||||||
}
|
|
||||||
else // no plugin subreading?
|
|
||||||
{
|
|
||||||
pCurrSubBuf=NULL; // -> return NULL as subc buffer to emu
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(SubAData,0,96); // init audio subc buffer
|
|
||||||
|
|
||||||
if(iUseSubReading!=2) return; // no subfile wanted?
|
|
||||||
if(szSUBF[0]==0) return; // no filename given?
|
|
||||||
|
|
||||||
subfile=fopen(szSUBF, "rb"); // open subfile
|
|
||||||
if(subfile==0)
|
|
||||||
{
|
|
||||||
MessageBox(NULL,"No SBI/M3S file found!",libraryName,MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer,0,5); // read header
|
|
||||||
fread(buffer, 4, 1, subfile);
|
|
||||||
|
|
||||||
iSUBNum=0;subHead=NULL;
|
|
||||||
|
|
||||||
if(strcmp((char *)buffer,"SBI")==0) // ah, SBI file
|
|
||||||
{
|
|
||||||
while(fread(buffer, 4, 1, subfile)==1) // -> read record header
|
|
||||||
{
|
|
||||||
iSUBNum++; // -> one more sub cache block
|
|
||||||
px=(SUB_DATA *)malloc(sizeof(SUB_DATA)); // -> get cache buff
|
|
||||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!! // -> and fill it...
|
|
||||||
|
|
||||||
/* TODO (#1#): addr2time subchannel */
|
|
||||||
|
|
||||||
|
|
||||||
px->addr=time2addrB(buffer);
|
|
||||||
|
|
||||||
px->pNext=NULL;
|
|
||||||
|
|
||||||
px->subq[0]=0x41;
|
|
||||||
px->subq[1]=0x01;
|
|
||||||
px->subq[2]=0x01;
|
|
||||||
p=&px->subq[3];
|
|
||||||
addr2timeB(px->addr,p);
|
|
||||||
px->subq[6]=0x00;
|
|
||||||
p=&px->subq[7];
|
|
||||||
addr2timeB(px->addr+150,p);
|
|
||||||
|
|
||||||
if(buffer[3]==1)
|
|
||||||
{
|
|
||||||
fread(px->subq,10, 1, subfile);
|
|
||||||
}
|
|
||||||
else if(buffer[3]==2)
|
|
||||||
{
|
|
||||||
fread(&px->subq[3],3, 1, subfile);
|
|
||||||
}
|
|
||||||
else if(buffer[3]==3)
|
|
||||||
{
|
|
||||||
fread(&px->subq[7],3, 1, subfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(plast==NULL) // add new cache block to linked list
|
|
||||||
{
|
|
||||||
plast=subHead=px;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plast->pNext=px;plast=px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // M3S file?
|
|
||||||
{ // -> read data, and store all
|
|
||||||
unsigned char min,sec,frame,xmin,xsec,xframe; // -> subs which are different from
|
|
||||||
BOOL b1,b2,goon=TRUE;int iNum=0; // -> the expected calculated values
|
|
||||||
|
|
||||||
xmin=2;
|
|
||||||
xsec=58;
|
|
||||||
xframe=0;
|
|
||||||
min=3;
|
|
||||||
sec=0;
|
|
||||||
frame=0;
|
|
||||||
|
|
||||||
fread(buffer+4, 12, 1, subfile);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(itod(min) != buffer[7]||
|
|
||||||
itod(sec) != buffer[8]||
|
|
||||||
itod(frame) != buffer[9])
|
|
||||||
b1=TRUE; else b1=FALSE;
|
|
||||||
|
|
||||||
if(itod(xmin) != buffer[3]||
|
|
||||||
itod(xsec) != buffer[4]||
|
|
||||||
itod(xframe) != buffer[5])
|
|
||||||
b2=TRUE; else b2=FALSE;
|
|
||||||
|
|
||||||
if(buffer[1]!=1) b1=b2=TRUE;
|
|
||||||
if(buffer[2]!=1) b1=b2=TRUE;
|
|
||||||
|
|
||||||
if(b1 || b2)
|
|
||||||
{
|
|
||||||
iSUBNum++;
|
|
||||||
px=(SUB_DATA *)malloc(sizeof(SUB_DATA));
|
|
||||||
px->pNext=NULL;
|
|
||||||
memcpy(px->subq,buffer,10);
|
|
||||||
buffer[7]=itod(min);
|
|
||||||
buffer[8]=itod(sec);
|
|
||||||
buffer[9]=itod(frame);
|
|
||||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
px->addr=time2addrB(&buffer[7]);
|
|
||||||
|
|
||||||
if(plast==NULL)
|
|
||||||
{plast=subHead=px;}
|
|
||||||
else {plast->pNext=px;plast=px;}
|
|
||||||
}
|
|
||||||
|
|
||||||
xframe=xframe+1;
|
|
||||||
if(xframe>74)
|
|
||||||
{
|
|
||||||
xsec+=1;
|
|
||||||
xframe-=75;
|
|
||||||
if(xsec>59)
|
|
||||||
{
|
|
||||||
xmin+=1;
|
|
||||||
xsec-=60;
|
|
||||||
if(xmin>99)
|
|
||||||
{
|
|
||||||
goon=FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
frame=frame+1;
|
|
||||||
if(frame>74)
|
|
||||||
{
|
|
||||||
sec+=1;
|
|
||||||
frame-=75;
|
|
||||||
if(sec>59)
|
|
||||||
{
|
|
||||||
min+=1;
|
|
||||||
sec-=60;
|
|
||||||
if(min>99)
|
|
||||||
{
|
|
||||||
goon=FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iNum++;
|
|
||||||
if(iNum>(60*75)) goon=FALSE;
|
|
||||||
}
|
|
||||||
while(goon && (fread(buffer, 16, 1, subfile)==1));
|
|
||||||
|
|
||||||
if(iNum!=(60*75)) goon=FALSE;
|
|
||||||
else
|
|
||||||
if(iSUBNum==(60*75)) goon=FALSE;
|
|
||||||
|
|
||||||
if(!goon)
|
|
||||||
{
|
|
||||||
MessageBox(NULL,"Bad SBI/M3S file!",libraryName,MB_OK);
|
|
||||||
fclose(subfile);
|
|
||||||
FreeSUBCache();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subCache=NULL;
|
|
||||||
if(iSUBNum) // something in cache?
|
|
||||||
{ // -> create an array with the used addresses, for fast searching access
|
|
||||||
SUB_CACHE * psc;int i;
|
|
||||||
subCache=(SUB_CACHE *)malloc(iSUBNum*sizeof(SUB_CACHE));
|
|
||||||
psc=subCache;px=subHead;
|
|
||||||
for(i=0;i<iSUBNum;i++,psc++,px=(SUB_DATA *)px->pNext)
|
|
||||||
{
|
|
||||||
psc->addr = px->addr;
|
|
||||||
psc->pNext = (void *)px;
|
|
||||||
}
|
|
||||||
iSUBNum--;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(subfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// func for calculating 'right' subdata
|
|
||||||
|
|
||||||
void FakeSubData(unsigned long adr)
|
|
||||||
{
|
|
||||||
SubCData[12]=0x41;
|
|
||||||
SubCData[13]=0x01;
|
|
||||||
SubCData[14]=0x01;
|
|
||||||
|
|
||||||
/* TODO (#1#): addr2time fake sub data
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//!!!!!!!!!!!!!!!!!!!!!!!????
|
|
||||||
addr2timeB(adr, &SubCData[15]);
|
|
||||||
// SubCData[18]=0x00;
|
|
||||||
addr2timeB(adr+150,&SubCData[19]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// check, if for a given addr we have special subdata in cache
|
|
||||||
|
|
||||||
void CheckSUBCache(long addr)
|
|
||||||
{
|
|
||||||
SUB_CACHE * pcstart, * pcend, * pcpos;
|
|
||||||
|
|
||||||
pcstart=subCache; // ptrs to address arrays (start/end)
|
|
||||||
pcend =subCache+iSUBNum;
|
|
||||||
|
|
||||||
if(addr>=pcstart->addr && // easy check, if given addr is between start/end
|
|
||||||
addr<=pcend->addr)
|
|
||||||
{
|
|
||||||
while(1) // now search for sub
|
|
||||||
{
|
|
||||||
if(addr==pcend->addr) {pcpos=pcend;break;} // got it! break
|
|
||||||
|
|
||||||
pcpos=pcstart+(pcend-pcstart)/2; // get the 'middle' address
|
|
||||||
if(pcpos==pcstart) break; // no more checks can be done
|
|
||||||
if(addr<pcpos->addr) // look further...
|
|
||||||
{
|
|
||||||
pcend=pcpos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(addr>pcpos->addr)
|
|
||||||
{
|
|
||||||
pcstart=pcpos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(addr==pcpos->addr) // found some cached data?
|
|
||||||
{
|
|
||||||
SUB_DATA * p=(SUB_DATA *)pcpos->pNext; // -> ptr to data
|
|
||||||
memcpy(&SubCData[12],p->subq,10); // -> get the data
|
|
||||||
return; // -> done
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FakeSubData(addr); // no subcdata avail, so fake right one
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// free all sub cache bufs
|
|
||||||
|
|
||||||
void FreeSUBCache(void)
|
|
||||||
{
|
|
||||||
SUB_DATA * p=subHead;
|
|
||||||
void * pn;
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
pn=p->pNext;
|
|
||||||
free(p);
|
|
||||||
p=(SUB_DATA *)pn;
|
|
||||||
}
|
|
||||||
subHead=NULL;
|
|
||||||
|
|
||||||
if(subCache) free(subCache);
|
|
||||||
subCache=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,30 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
sub.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void BuildSUBCache(void);
|
|
||||||
void FakeSubData(unsigned long adr);
|
|
||||||
void CheckSUBCache(long addr);
|
|
||||||
void FreeSUBCache(void);
|
|
|
@ -1,105 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
toc.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Nov 16 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/11/16 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#define _IN_TOC
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TOC sTOC;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// read toc
|
|
||||||
|
|
||||||
|
|
||||||
void ReadTOC(void)
|
|
||||||
{
|
|
||||||
unsigned char xbuffer[4];DWORD dwStatus;
|
|
||||||
|
|
||||||
LockGenCDAccess();
|
|
||||||
|
|
||||||
memset(&(sTOC),0,sizeof(sTOC)); // init toc infos
|
|
||||||
|
|
||||||
dwStatus=GetSCSITOC((LPTOC)&sTOC); // get toc by scsi... may change that for ioctrl in xp/2k?
|
|
||||||
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
if(dwStatus!=SS_COMP) return;
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("TOC Last %d, max %08x,%08x\n",sTOC.cLastTrack,sTOC.tracks[sTOC.cLastTrack].lAddr,reOrder(sTOC.tracks[sTOC.cLastTrack].lAddr));
|
|
||||||
#endif
|
|
||||||
// re-order it to psemu pro standards
|
|
||||||
addr2time(reOrder(sTOC.tracks[sTOC.cLastTrack].lAddr),xbuffer);
|
|
||||||
|
|
||||||
#ifdef DBGOUT
|
|
||||||
auxprintf("TOC %d, %d, %d, %d\n",
|
|
||||||
xbuffer[0],xbuffer[1],xbuffer[2],xbuffer[3] );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xbuffer[0]=itob(xbuffer[0]);
|
|
||||||
xbuffer[1]=itob(xbuffer[1]);
|
|
||||||
xbuffer[2]=itob(xbuffer[2]);
|
|
||||||
xbuffer[3]=itob(xbuffer[3]);
|
|
||||||
lMaxAddr=time2addrB(xbuffer); // get max data adr
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// get the highest address of first (=data) track
|
|
||||||
|
|
||||||
unsigned long GetLastTrack1Addr(void)
|
|
||||||
{
|
|
||||||
unsigned char xbuffer[4];DWORD dwStatus;
|
|
||||||
unsigned long lmax;
|
|
||||||
TOC xTOC;
|
|
||||||
|
|
||||||
LockGenCDAccess();
|
|
||||||
|
|
||||||
memset(&(xTOC),0,sizeof(xTOC));
|
|
||||||
|
|
||||||
dwStatus=GetSCSITOC((LPTOC)&xTOC);
|
|
||||||
|
|
||||||
UnlockGenCDAccess();
|
|
||||||
|
|
||||||
if(dwStatus!=SS_COMP) return 0;
|
|
||||||
|
|
||||||
addr2time(reOrder(xTOC.tracks[1].lAddr),xbuffer);
|
|
||||||
|
|
||||||
xbuffer[0]=itob(xbuffer[0]);
|
|
||||||
xbuffer[1]=itob(xbuffer[1]);
|
|
||||||
xbuffer[2]=itob(xbuffer[2]);
|
|
||||||
xbuffer[3]=itob(xbuffer[3]);
|
|
||||||
|
|
||||||
lmax=time2addrB(xbuffer);
|
|
||||||
if(lmax<150) return 0;
|
|
||||||
|
|
||||||
return lmax-150;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
|
@ -1,28 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
toc.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Sep 18 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/09/19 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void ReadTOC(void);
|
|
||||||
unsigned long GetLastTrack1Addr(void);
|
|
|
@ -1,61 +0,0 @@
|
||||||
--------------------------------------------------------------------------
|
|
||||||
25. December, 2004 Version 1.2
|
|
||||||
|
|
||||||
- The plugin is tested with PCSX2 0.7!
|
|
||||||
|
|
||||||
- I've repaired a stupid bug concerning calculating the track sizes.
|
|
||||||
|
|
||||||
- I've added an hack for big DVDs (fake minute info in the CDVDgetTD
|
|
||||||
function).
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
29. March, 2004 Version 1.1
|
|
||||||
|
|
||||||
- Ah, to make it short: I've got some times this weekend, tried the
|
|
||||||
PCSX2 0.6 version, noticed that my relatively new Plextor PX-708A
|
|
||||||
drive didn't work with the P.E.Op.S. dvd plugin, and therefore
|
|
||||||
added a new good working reading mode.
|
|
||||||
|
|
||||||
So, if you had just some error message like 'unable to open dvd
|
|
||||||
plugin' with PCSX2 and the P.E.Op.S. dvd plugin in the past, chances
|
|
||||||
are high that this version will now give better results on your
|
|
||||||
system. At least I was able to see the first intro screens of some
|
|
||||||
games without problems :)
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
19. November, 2003 Version 1.0
|
|
||||||
|
|
||||||
- What to say? Blame Shadow of the PCSX2 team... he wanted
|
|
||||||
a PS2 CDVD plugin from me, and he didn't give up asking until
|
|
||||||
I made one, sigh ;)
|
|
||||||
|
|
||||||
Ok, I have done this plugin using my old P.E.Op.S. PSX cdr
|
|
||||||
plugin sources, so you will notice some similaries, of course.
|
|
||||||
|
|
||||||
This plugin is able to play PS2 CDs and PS2 DVDs in your
|
|
||||||
PC's CD/DVD drives, and since all the old P.E.Op.S. cdr read
|
|
||||||
caching modes are available, the speed should be fine as well.
|
|
||||||
|
|
||||||
For the plugin settings, check out the included readme file
|
|
||||||
(but if you are familar with the P.E.Op.S. cdr config, you
|
|
||||||
will not have much troubles... the new plugin's config is even
|
|
||||||
easier to use, since you don't have to specify a read method).
|
|
||||||
|
|
||||||
I cannot say much about compatibility (since I did the plugin
|
|
||||||
in a few hours last weekend, and I only have a Liteon DVD drive
|
|
||||||
for tests available right now), but I think it's free of major
|
|
||||||
bugs, so feel free to try it.
|
|
||||||
|
|
||||||
Some stuff is not available right now: PPF support and subchannel
|
|
||||||
reading, for example (but both are not very important at the
|
|
||||||
moment, imho).
|
|
||||||
|
|
||||||
The sources of the plugin (license: GPL) can be found on the
|
|
||||||
P.E.Op.S. site on sourceforge, I've added a MS VisualStudio 6
|
|
||||||
project file, as well as a Bloodshed Dev-C++ one (you will
|
|
||||||
also need NASM for this one).
|
|
||||||
|
|
||||||
Ok, have fun :)
|
|
|
@ -1,354 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
**
|
|
||||||
** Module Name: wnaspi32.h
|
|
||||||
**
|
|
||||||
** Description: Header file for ASPI for Win32. This header includes
|
|
||||||
** macro and type declarations, and can be included without
|
|
||||||
** modification when using Borland C++ or Microsoft Visual
|
|
||||||
** C++ with 32-bit compilation. If you are using a different
|
|
||||||
** compiler then you MUST ensure that structures are packed
|
|
||||||
** onto byte alignments, and that C++ name mangling is turned
|
|
||||||
** off.
|
|
||||||
**
|
|
||||||
** Notes: This file created using 4 spaces per tab.
|
|
||||||
**
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __WNASPI32_H__
|
|
||||||
#define __WNASPI32_H__
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Make sure structures are packed and undecorated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma option -a1
|
|
||||||
#endif //__BORLANDC__
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif //__MSC_VER
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif //__cplusplus
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SCSI MISCELLANEOUS EQUATES %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
#define SENSE_LEN 14 // Default sense buffer length
|
|
||||||
#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI
|
|
||||||
#define SRB_POSTING 0x01 // Enable ASPI posting
|
|
||||||
#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting
|
|
||||||
#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host
|
|
||||||
#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target
|
|
||||||
#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI event notification
|
|
||||||
|
|
||||||
#define RESIDUAL_COUNT_SUPPORTED 0x02 // Extended buffer flag
|
|
||||||
#define MAX_SRB_TIMEOUT 108000lu // 30 hour maximum timeout in s
|
|
||||||
#define DEFAULT_SRB_TIMEOUT 108000lu // Max timeout by default
|
|
||||||
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% ASPI Command Definitions %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
#define SC_HA_INQUIRY 0x00 // Host adapter inquiry
|
|
||||||
#define SC_GET_DEV_TYPE 0x01 // Get device type
|
|
||||||
#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command
|
|
||||||
#define SC_ABORT_SRB 0x03 // Abort an SRB
|
|
||||||
#define SC_RESET_DEV 0x04 // SCSI bus device reset
|
|
||||||
#define SC_SET_HA_PARMS 0x05 // Set HA parameters
|
|
||||||
#define SC_GET_DISK_INFO 0x06 // Get Disk information
|
|
||||||
#define SC_RESCAN_SCSI_BUS 0x07 // ReBuild SCSI device map
|
|
||||||
#define SC_GETSET_TIMEOUTS 0x08 // Get/Set target timeouts
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB Status %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
#define SS_PENDING 0x00 // SRB being processed
|
|
||||||
#define SS_COMP 0x01 // SRB completed without error
|
|
||||||
#define SS_ABORTED 0x02 // SRB aborted
|
|
||||||
#define SS_ABORT_FAIL 0x03 // Unable to abort SRB
|
|
||||||
#define SS_ERR 0x04 // SRB completed with error
|
|
||||||
|
|
||||||
#define SS_INVALID_CMD 0x80 // Invalid ASPI command
|
|
||||||
#define SS_INVALID_HA 0x81 // Invalid host adapter number
|
|
||||||
#define SS_NO_DEVICE 0x82 // SCSI device not installed
|
|
||||||
|
|
||||||
#define SS_INVALID_SRB 0xE0 // Invalid parameter set in SRB
|
|
||||||
#define SS_OLD_MANAGER 0xE1 // ASPI manager doesn't support Windows
|
|
||||||
#define SS_BUFFER_ALIGN 0xE1 // Buffer not aligned (replaces OLD_MANAGER in Win32)
|
|
||||||
#define SS_ILLEGAL_MODE 0xE2 // Unsupported Windows mode
|
|
||||||
#define SS_NO_ASPI 0xE3 // No ASPI managers resident
|
|
||||||
#define SS_FAILED_INIT 0xE4 // ASPI for windows failed init
|
|
||||||
#define SS_ASPI_IS_BUSY 0xE5 // No resources available to execute cmd
|
|
||||||
#define SS_BUFFER_TO_BIG 0xE6 // Buffer size to big to handle!
|
|
||||||
#define SS_MISMATCHED_COMPONENTS 0xE7 // The DLLs/EXEs of ASPI don't version check
|
|
||||||
#define SS_NO_ADAPTERS 0xE8 // No host adapters to manage
|
|
||||||
#define SS_INSUFFICIENT_RESOURCES 0xE9 // Couldn't allocate resources needed to init
|
|
||||||
#define SS_ASPI_IS_SHUTDOWN 0xEA // Call came to ASPI after PROCESS_DETACH
|
|
||||||
#define SS_BAD_INSTALL 0xEB // The DLL or other components are installed wrong
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% Host Adapter Status %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
#define HASTAT_OK 0x00 // Host adapter did not detect an // error
|
|
||||||
#define HASTAT_SEL_TO 0x11 // Selection Timeout
|
|
||||||
#define HASTAT_DO_DU 0x12 // Data overrun data underrun
|
|
||||||
#define HASTAT_BUS_FREE 0x13 // Unexpected bus free
|
|
||||||
#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence // failure
|
|
||||||
#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was waiting to beprocessed.
|
|
||||||
#define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB.
|
|
||||||
#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the // adapter received a MESSAGE
|
|
||||||
#define HASTAT_BUS_RESET 0x0E // A bus reset was detected.
|
|
||||||
#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected.
|
|
||||||
#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY (0) %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_HA_INQUIRY
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
|
||||||
BYTE HA_Count; // 08/008 Number of host adapters present
|
|
||||||
BYTE HA_SCSI_ID; // 09/009 SCSI ID of host adapter
|
|
||||||
BYTE HA_ManagerId[16]; // 0A/010 String describing the manager
|
|
||||||
BYTE HA_Identifier[16]; // 1A/026 String describing the host adapter
|
|
||||||
BYTE HA_Unique[16]; // 2A/042 Host Adapter Unique parameters
|
|
||||||
WORD HA_Rsvd1; // 3A/058 Reserved, MUST = 0
|
|
||||||
}
|
|
||||||
SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_GET_DEV_TYPE */
|
|
||||||
BYTE SRB_Status; /* 01/001 ASPI command status byte */
|
|
||||||
BYTE SRB_HaID; /* 02/002 ASPI host adapter number */
|
|
||||||
BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */
|
|
||||||
DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */
|
|
||||||
BYTE SRB_Target; /* 08/008 Target's SCSI ID */
|
|
||||||
BYTE SRB_Lun; /* 09/009 Target's LUN number */
|
|
||||||
BYTE SRB_DeviceType; /* 0a/010 Target's peripheral device type */
|
|
||||||
BYTE SRB_Rsvd1; /* 0b/011 Reserved, must = 0 */
|
|
||||||
BYTE pad[68];
|
|
||||||
} SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
|
|
||||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
|
||||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
|
||||||
WORD SRB_Rsvd1; // 0A/010 Reserved for Alignment
|
|
||||||
DWORD SRB_BufLen; // 0C/012 Data Allocation Length
|
|
||||||
BYTE FAR *SRB_BufPointer; // 10/016 Data Buffer Pointer
|
|
||||||
BYTE SRB_SenseLen; // 14/020 Sense Allocation Length
|
|
||||||
BYTE SRB_CDBLen; // 15/021 CDB Length
|
|
||||||
BYTE SRB_HaStat; // 16/022 Host Adapter Status
|
|
||||||
BYTE SRB_TargStat; // 17/023 Target Status
|
|
||||||
VOID FAR *SRB_PostProc; // 18/024 Post routine
|
|
||||||
BYTE SRB_Rsvd2[20]; // 1C/028 Reserved, MUST = 0
|
|
||||||
BYTE CDBByte[16]; // 30/048 SCSI CDB
|
|
||||||
BYTE SenseArea[SENSE_LEN+2]; // 50/064 Request Sense buffer
|
|
||||||
}
|
|
||||||
SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - ABORT AN SRB - SC_ABORT_SRB (3) %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_ABORT_SRB
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 Reserved
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
|
|
||||||
VOID FAR *SRB_ToAbort; // 08/008 Pointer to SRB to abort
|
|
||||||
}
|
|
||||||
SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV (4) %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESET_DEV
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
|
|
||||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
|
||||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
|
||||||
BYTE SRB_Rsvd1[12]; // 0A/010 Reserved for Alignment
|
|
||||||
BYTE SRB_HaStat; // 16/022 Host Adapter Status
|
|
||||||
BYTE SRB_TargStat; // 17/023 Target Status
|
|
||||||
VOID FAR *SRB_PostProc; // 18/024 Post routine
|
|
||||||
BYTE SRB_Rsvd2[36]; // 1C/028 Reserved, MUST = 0
|
|
||||||
}
|
|
||||||
SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DISK_INFO
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 Reserved, MUST = 0
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
|
||||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
|
||||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
|
||||||
BYTE SRB_DriveFlags; // 0A/010 Driver flags
|
|
||||||
BYTE SRB_Int13HDriveInfo; // 0B/011 Host Adapter Status
|
|
||||||
BYTE SRB_Heads; // 0C/012 Preferred number of heads translation
|
|
||||||
BYTE SRB_Sectors; // 0D/013 Preferred number of sectors translation
|
|
||||||
BYTE SRB_Rsvd1[10]; // 0E/014 Reserved, MUST = 0
|
|
||||||
}
|
|
||||||
SRB_GetDiskInfo, *PSRB_GetDiskInfo, FAR *LPSRB_GetDiskInfo;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - RESCAN SCSI BUS(ES) ON SCSIPORT %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESCAN_SCSI_BUS
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 Reserved, MUST = 0
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
|
||||||
}
|
|
||||||
SRB_RescanPort, *PSRB_RescanPort, FAR *LPSRB_RescanPort;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% SRB - GET/SET TARGET TIMEOUTS %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GETSET_TIMEOUTS
|
|
||||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
|
||||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
|
||||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
|
||||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
|
||||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
|
||||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
|
||||||
DWORD SRB_Timeout; // 0A/010 Timeout in half seconds
|
|
||||||
}
|
|
||||||
SRB_GetSetTimeouts, *PSRB_GetSetTimeouts, FAR *LPSRB_GetSetTimeouts;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% ASPIBUFF - Structure For Controllng I/O Buffers %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct tag_ASPI32BUFF // Offset
|
|
||||||
{ // HX/DEC
|
|
||||||
PBYTE AB_BufPointer; // 00/000 Pointer to the ASPI allocated buffer
|
|
||||||
DWORD AB_BufLen; // 04/004 Length in bytes of the buffer
|
|
||||||
DWORD AB_ZeroFill; // 08/008 Flag set to 1 if buffer should be zeroed
|
|
||||||
DWORD AB_Reserved; // 0C/012 Reserved
|
|
||||||
}
|
|
||||||
ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% TOC structures %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned char reserved1;
|
|
||||||
unsigned char cAdrCtrl;
|
|
||||||
unsigned char cTrackNum;
|
|
||||||
unsigned char reserved2;
|
|
||||||
unsigned long lAddr;
|
|
||||||
} TOC_TRACK;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned short usTocDataLen;
|
|
||||||
unsigned char cFirstTrack;
|
|
||||||
unsigned char cLastTrack;
|
|
||||||
TOC_TRACK tracks[100];
|
|
||||||
} TOC, *PTOC, FAR *LPTOC;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// %%% PROTOTYPES - User Callable ASPI for Win32 Functions %%%
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
BYTE SRB_Cmd;
|
|
||||||
BYTE SRB_Status;
|
|
||||||
BYTE SRB_HaId;
|
|
||||||
BYTE SRB_Flags;
|
|
||||||
DWORD SRB_Hdr_Rsvd;
|
|
||||||
} SRB, *PSRB, FAR *LPSRB;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__BORLANDC__)
|
|
||||||
|
|
||||||
DWORD _import GetASPI32SupportInfo( void );
|
|
||||||
DWORD _import SendASPI32Command( LPSRB );
|
|
||||||
BOOL _import GetASPI32Buffer( PASPI32BUFF );
|
|
||||||
BOOL _import FreeASPI32Buffer( PASPI32BUFF );
|
|
||||||
BOOL _import TranslateASPI32Address( PDWORD, PDWORD );
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
|
|
||||||
__declspec(dllimport) DWORD GetASPI32SupportInfo( void );
|
|
||||||
__declspec(dllimport) DWORD SendASPI32Command( LPSRB );
|
|
||||||
__declspec(dllimport) BOOL GetASPI32Buffer( PASPI32BUFF );
|
|
||||||
__declspec(dllimport) BOOL FreeASPI32Buffer( PASPI32BUFF );
|
|
||||||
__declspec(dllimport) BOOL TranslateASPI32Address( PDWORD, PDWORD );
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
extern DWORD GetASPI32SupportInfo( void );
|
|
||||||
extern DWORD GetASPI32Command( LPSRB );
|
|
||||||
extern BOOL GetASPI32Buffer( PASPI32BUFF );
|
|
||||||
extern BOOL FreeASPI32Buffer( PASPI32BUFF );
|
|
||||||
extern BOOL TranslateASPI32Address( PDWORD, PDWORD );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Restore compiler default packing and close off the C declarations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma option -a.
|
|
||||||
#endif //__BORLANDC__
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif //_MSC_VER
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif //__cplusplus
|
|
||||||
|
|
||||||
#endif //__WNASPI32_H__
|
|
|
@ -14,10 +14,6 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/CDVDnull" AND CDVDnull)
|
||||||
add_subdirectory(CDVDnull)
|
add_subdirectory(CDVDnull)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/CDVDpeops" AND CDVDpeops)
|
|
||||||
# add_subdirectory(CDVDpeops)
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/dev9null" AND dev9null)
|
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/dev9null" AND dev9null)
|
||||||
add_subdirectory(dev9null)
|
add_subdirectory(dev9null)
|
||||||
endif()
|
endif()
|
||||||
|
@ -58,10 +54,6 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/PadNull" AND PadNull)
|
||||||
add_subdirectory(PadNull)
|
add_subdirectory(PadNull)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/PeopsSPU2" AND PeopsSPU2)
|
|
||||||
# add_subdirectory(PeopsSPU2)
|
|
||||||
# endif()
|
|
||||||
|
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/SPU2null" AND SPU2null)
|
if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/SPU2null" AND SPU2null)
|
||||||
add_subdirectory(SPU2null)
|
add_subdirectory(SPU2null)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
#########################################################################
|
|
||||||
|
|
||||||
- spu.c / spu.h
|
|
||||||
main spu handler - generic init and exit funcs
|
|
||||||
|
|
||||||
- adsr.c / adsr.h
|
|
||||||
adsr handlers
|
|
||||||
|
|
||||||
- dma.c / dma.h
|
|
||||||
memory transfer funcs
|
|
||||||
|
|
||||||
- registers.c / registers.h / regs.h
|
|
||||||
spu register handling
|
|
||||||
|
|
||||||
- reverb.c / reverb.h
|
|
||||||
simple reverb handlers
|
|
||||||
|
|
||||||
- xa.c / xa.h
|
|
||||||
xa sound handlers
|
|
||||||
|
|
||||||
- cfg.c / cfg.h
|
|
||||||
configuration dialogs/file reading funcs
|
|
||||||
|
|
||||||
- dsound.c / oss.c / dsoundoss.h
|
|
||||||
Windows/Linux sound interfaces
|
|
||||||
|
|
||||||
- freeze.c
|
|
||||||
save state laoding/saving
|
|
||||||
|
|
||||||
- spu2PeopsSound.*
|
|
||||||
Windows dll related files (including msvc project files)
|
|
||||||
|
|
||||||
- Makefile
|
|
||||||
Linux makefile... just do a "make" command to build the plugin
|
|
||||||
|
|
||||||
- stdafx.h
|
|
||||||
main include file
|
|
||||||
|
|
||||||
- externals.h
|
|
||||||
generic defines/external vars
|
|
||||||
|
|
||||||
- psemuxa.h
|
|
||||||
psemu pro xa definitions
|
|
||||||
|
|
||||||
- resource.h
|
|
||||||
Windows resource header
|
|
||||||
|
|
||||||
#########################################################################
|
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
##############################################################################
|
|
||||||
# MAKEFILE FOR THE PEOPS OSS SPU2... just run "make"
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# 1. SETS (CCFLAGS3 is used)
|
|
||||||
##############################################################################
|
|
||||||
all: spu2PeopsOSS
|
|
||||||
install: all
|
|
||||||
|
|
||||||
# Set to TRUE to build the ALSA support
|
|
||||||
USEALSA = FALSE
|
|
||||||
# Set to TRUE to disable the thread library support - helpful for some Linux distros
|
|
||||||
NOTHREADLIB = FALSE
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CCFLAGS1 = -fPIC -c -Wall -O3 -m32
|
|
||||||
CCFLAGS2 = -fPIC -c -Wall -O2 -ffast-math -m32
|
|
||||||
CCFLAGS3 = -fPIC -c -Wall -O3 -ffast-math -fomit-frame-pointer -m32
|
|
||||||
|
|
||||||
INCLUDE =
|
|
||||||
LINK = gcc
|
|
||||||
OBJ = spu.o dma.o freeze.o registers.o
|
|
||||||
LIB = -lc -lm
|
|
||||||
|
|
||||||
ifeq ($(USEALSA), TRUE)
|
|
||||||
OBJ+= alsa.o
|
|
||||||
LIB+= -lasound
|
|
||||||
LINKFLAGS = -m32 -shared -Wl,-soname,libspu2PeopsALSA.so -o libspu2PeopsALSA.so.1.0.3
|
|
||||||
CCFLAGS3+= -DUSEALSA
|
|
||||||
else
|
|
||||||
OBJ+= oss.o
|
|
||||||
LINKFLAGS = -m32 -shared -Wl,-soname,libspu2PeopsOSS.so.1.6 -fPIC -fomit-frame-pointer -o libspu2PeopsOSS.so.1.6
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(NOTHREADLIB), TRUE)
|
|
||||||
CCFLAGS3+= -DNOTHREADLIB
|
|
||||||
else
|
|
||||||
LIB+= -lpthread
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# 2. MAIN RULE
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
spu2PeopsOSS : $(OBJ)
|
|
||||||
$(LINK) $(LINKFLAGS) $(OBJ) $(LIB)
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# 3. GENERAL RULES
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
%.o : %.c
|
|
||||||
$(CC) $(CCFLAGS3) $(INCLUDE) $<
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# 4. SPECIFIC RULES
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
spu.o : spu.c stdafx.h externals.h cfg.h dsoundoss.h regs.h debug.h xa.c reverb.c adsr.c
|
|
||||||
cfg.o : stdafx.h externals.h
|
|
||||||
dma.o : dma.c stdafx.h externals.h
|
|
||||||
freeze.o : freeze.c stdafx.h externals.h registers.h spu.h regs.h
|
|
||||||
oss.o : oss.c stdafx.h externals.h
|
|
||||||
alsa.o : alsa.h stdafx.h externals.h
|
|
||||||
registers.o : registers.c stdafx.h externals.h registers.h regs.h reverb.h
|
|
||||||
|
|
||||||
.PHONY: clean spu2PeopsOSS
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o *.so.*
|
|
|
@ -1,79 +0,0 @@
|
||||||
# Project: spu2PeopsSound
|
|
||||||
# Makefile created by Dev-C++ 4.9.9.2
|
|
||||||
|
|
||||||
CPP = g++.exe
|
|
||||||
CC = gcc.exe
|
|
||||||
WINDRES = windres.exe
|
|
||||||
RES = Release/spu2PeopsSound_private.res
|
|
||||||
OBJ = Release/adsr.o Release/alsa.o Release/cfg.o Release/debug.o Release/dma.o Release/dsound.o Release/freeze.o Release/oss.o Release/record.o Release/registers.o Release/reverb.o Release/spu.o Release/spu2PeopsSound.o Release/StdAfx.o Release/xa.o $(RES)
|
|
||||||
LINKOBJ = Release/adsr.o Release/alsa.o Release/cfg.o Release/debug.o Release/dma.o Release/dsound.o Release/freeze.o Release/oss.o Release/record.o Release/registers.o Release/reverb.o Release/spu.o Release/spu2PeopsSound.o Release/StdAfx.o Release/xa.o $(RES)
|
|
||||||
LIBS = -L"lib" -ldsound -lwinmm -luser32 -lgdi32 -ladvapi32 --add-stdcall-alias
|
|
||||||
INCS = -I"include" -I"D:/Archivos de programa/Microsoft Visual Studio .NET 2003/SDK/v1.1/include"
|
|
||||||
CXXINCS = -I"lib/gcc/mingw32/3.4.2/include" -I"include/c++/3.4.2/backward" -I"include/c++/3.4.2/mingw32" -I"include/c++/3.4.2" -I"include"
|
|
||||||
BIN = ../SPU2PeopsDSound.dll
|
|
||||||
CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -mcpu=pentium -D_M_IX86=500 -W -DWIN32 -DNDEBUG -D_WINDOWS -D_GCC -O3
|
|
||||||
CFLAGS = $(INCS) -D__GNUWIN32__ -mcpu=pentium -D_M_IX86=500 -W -DWIN32 -DNDEBUG -D_WINDOWS -D_GCC -O3
|
|
||||||
RM = rm -f
|
|
||||||
|
|
||||||
.PHONY: all all-before all-after clean clean-custom
|
|
||||||
|
|
||||||
all: all-before ../SPU2PeopsDSound.dll all-after
|
|
||||||
|
|
||||||
|
|
||||||
clean: clean-custom
|
|
||||||
${RM} $(OBJ) $(BIN)
|
|
||||||
|
|
||||||
DLLWRAP=dllwrap.exe
|
|
||||||
DEFFILE=../libSPU2PeopsDSound.def
|
|
||||||
STATICLIB=../libSPU2PeopsDSound.a
|
|
||||||
|
|
||||||
$(BIN): $(LINKOBJ)
|
|
||||||
$(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
|
|
||||||
|
|
||||||
Release/adsr.o: adsr.c
|
|
||||||
$(CC) -c adsr.c -o Release/adsr.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/alsa.o: alsa.c
|
|
||||||
$(CC) -c alsa.c -o Release/alsa.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/cfg.o: cfg.c
|
|
||||||
$(CC) -c cfg.c -o Release/cfg.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/debug.o: debug.c
|
|
||||||
$(CC) -c debug.c -o Release/debug.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/dma.o: dma.c
|
|
||||||
$(CC) -c dma.c -o Release/dma.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/dsound.o: dsound.c
|
|
||||||
$(CC) -c dsound.c -o Release/dsound.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/freeze.o: freeze.c
|
|
||||||
$(CC) -c freeze.c -o Release/freeze.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/oss.o: oss.c
|
|
||||||
$(CC) -c oss.c -o Release/oss.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/record.o: record.c
|
|
||||||
$(CC) -c record.c -o Release/record.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/registers.o: registers.c
|
|
||||||
$(CC) -c registers.c -o Release/registers.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/reverb.o: reverb.c
|
|
||||||
$(CC) -c reverb.c -o Release/reverb.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/spu.o: spu.c
|
|
||||||
$(CC) -c spu.c -o Release/spu.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/spu2PeopsSound.o: spu2PeopsSound.c
|
|
||||||
$(CC) -c spu2PeopsSound.c -o Release/spu2PeopsSound.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/StdAfx.o: StdAfx.c
|
|
||||||
$(CC) -c StdAfx.c -o Release/StdAfx.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/xa.o: xa.c
|
|
||||||
$(CC) -c xa.c -o Release/xa.o $(CFLAGS)
|
|
||||||
|
|
||||||
Release/spu2PeopsSound_private.res: spu2PeopsSound_private.rc
|
|
||||||
$(WINDRES) -i spu2PeopsSound_private.rc --input-format=rc -o Release/spu2PeopsSound_private.res -O coff
|
|
|
@ -1,17 +0,0 @@
|
||||||
/nologo /o"Release/spu2PeopsSound.bsc"
|
|
||||||
".\Release\adsr.sbr"
|
|
||||||
".\Release\alsa.sbr"
|
|
||||||
".\Release\cfg.sbr"
|
|
||||||
".\Release\debug.sbr"
|
|
||||||
".\Release\dma.sbr"
|
|
||||||
".\Release\dsound.sbr"
|
|
||||||
".\Release\freeze.sbr"
|
|
||||||
".\Release\oss.sbr"
|
|
||||||
".\Release\psemu.sbr"
|
|
||||||
".\Release\record.sbr"
|
|
||||||
".\Release\registers.sbr"
|
|
||||||
".\Release\reverb.sbr"
|
|
||||||
".\Release\spu.sbr"
|
|
||||||
".\Release\spu2PeopsSound.sbr"
|
|
||||||
".\Release\StdAfx.sbr"
|
|
||||||
".\Release\xa.sbr"
|
|
|
@ -1,668 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
adsr.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/05/14 - xodnizel
|
|
||||||
// - removed stopping of reverb on sample end
|
|
||||||
//
|
|
||||||
// 2003/01/06 - Pete
|
|
||||||
// - added Neill's ADSR timings
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_ADSR
|
|
||||||
|
|
||||||
// will be included from spu.c
|
|
||||||
#ifdef _IN_SPU
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// ADSR func
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
unsigned long RateTable[160];
|
|
||||||
|
|
||||||
void InitADSR(void) // INIT ADSR
|
|
||||||
{
|
|
||||||
unsigned long r,rs,rd;int i;
|
|
||||||
|
|
||||||
memset(RateTable,0,sizeof(unsigned long)*160); // build the rate table according to Neill's rules (see at bottom of file)
|
|
||||||
|
|
||||||
r=3;rs=1;rd=0;
|
|
||||||
|
|
||||||
for(i=32;i<160;i++) // we start at pos 32 with the real values... everything before is 0
|
|
||||||
{
|
|
||||||
if(r<0x3FFFFFFF)
|
|
||||||
{
|
|
||||||
r+=rs;
|
|
||||||
rd++;if(rd==5) {rd=1;rs*=2;}
|
|
||||||
}
|
|
||||||
if(r>0x3FFFFFFF) r=0x3FFFFFFF;
|
|
||||||
|
|
||||||
RateTable[i]=r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE void StartADSR(int ch) // MIX ADSR
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
|
|
||||||
s_chan[ch].ADSRX.State=0;
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE int MixADSR(int ch) // MIX ADSR
|
|
||||||
{
|
|
||||||
if(s_chan[ch].bStop) // should be stopped:
|
|
||||||
{
|
|
||||||
if(s_chan[ch].bIgnoreLoop==0){
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol=0;
|
|
||||||
s_chan[ch].bOn=0;
|
|
||||||
s_chan[ch].pStart= NULL; //FFX U and E need this else the speech never ends
|
|
||||||
s_chan[ch].pLoop= s_chan[ch].pCurr; //FFX J needs this else speech never plays :P
|
|
||||||
s_chan[ch].bStop=1;
|
|
||||||
s_chan[ch].bIgnoreLoop=0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(s_chan[ch].ADSRX.ReleaseModeExp)// do release
|
|
||||||
{
|
|
||||||
switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
|
|
||||||
{
|
|
||||||
case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +0 + 32]; break;
|
|
||||||
case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +4 + 32]; break;
|
|
||||||
case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +6 + 32]; break;
|
|
||||||
case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +8 + 32]; break;
|
|
||||||
case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +9 + 32]; break;
|
|
||||||
case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +10+ 32]; break;
|
|
||||||
case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +11+ 32]; break;
|
|
||||||
case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +12+ 32]; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0)
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol=0;
|
|
||||||
s_chan[ch].bOn=0;
|
|
||||||
s_chan[ch].bStop=1;
|
|
||||||
s_chan[ch].bIgnoreLoop=0;
|
|
||||||
//s_chan[ch].bReverb=0;
|
|
||||||
//s_chan[ch].bNoise=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
|
|
||||||
s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
|
|
||||||
return s_chan[ch].ADSRX.lVolume;
|
|
||||||
}
|
|
||||||
else // not stopped yet?
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.State==0) // -> attack
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.AttackModeExp)
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
|
|
||||||
else
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0)
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
|
|
||||||
s_chan[ch].ADSRX.State=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
|
|
||||||
return s_chan[ch].ADSRX.lVolume;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------//
|
|
||||||
if(s_chan[ch].ADSRX.State==1) // -> decay
|
|
||||||
{
|
|
||||||
switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
|
|
||||||
{
|
|
||||||
case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+0 + 32]; break;
|
|
||||||
case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+4 + 32]; break;
|
|
||||||
case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+6 + 32]; break;
|
|
||||||
case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+8 + 32]; break;
|
|
||||||
case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+9 + 32]; break;
|
|
||||||
case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+10+ 32]; break;
|
|
||||||
case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+11+ 32]; break;
|
|
||||||
case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+12+ 32]; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;
|
|
||||||
if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.State=2;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
|
|
||||||
return s_chan[ch].ADSRX.lVolume;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------//
|
|
||||||
if(s_chan[ch].ADSRX.State==2) // -> sustain
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.SustainIncrease)
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.SustainModeExp)
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
|
|
||||||
else
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0)
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSRX.SustainModeExp)
|
|
||||||
{
|
|
||||||
switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
|
|
||||||
{
|
|
||||||
case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +0 + 32];break;
|
|
||||||
case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +4 + 32];break;
|
|
||||||
case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +6 + 32];break;
|
|
||||||
case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +8 + 32];break;
|
|
||||||
case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +9 + 32];break;
|
|
||||||
case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +10+ 32];break;
|
|
||||||
case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +11+ 32];break;
|
|
||||||
case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +12+ 32];break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s_chan[ch].ADSRX.EnvelopeVol<0)
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSRX.EnvelopeVol=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
|
|
||||||
return s_chan[ch].ADSRX.lVolume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
James Higgs ADSR investigations:
|
|
||||||
|
|
||||||
PSX SPU Envelope Timings
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
First, here is an extract from doomed's SPU doc, which explains the basics
|
|
||||||
of the SPU "volume envelope":
|
|
||||||
|
|
||||||
*** doomed doc extract start ***
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
Voices.
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
The SPU has 24 hardware voices. These voices can be used to reproduce sample
|
|
||||||
data, noise or can be used as frequency modulator on the next voice.
|
|
||||||
Each voice has it's own programmable ADSR envelope filter. The main volume
|
|
||||||
can be programmed independently for left and right output.
|
|
||||||
|
|
||||||
The ADSR envelope filter works as follows:
|
|
||||||
Ar = Attack rate, which specifies the speed at which the volume increases
|
|
||||||
from zero to it's maximum value, as soon as the note on is given. The
|
|
||||||
slope can be set to lineair or exponential.
|
|
||||||
Dr = Decay rate specifies the speed at which the volume decreases to the
|
|
||||||
sustain level. Decay is always decreasing exponentially.
|
|
||||||
Sl = Sustain level, base level from which sustain starts.
|
|
||||||
Sr = Sustain rate is the rate at which the volume of the sustained note
|
|
||||||
increases or decreases. This can be either lineair or exponential.
|
|
||||||
Rr = Release rate is the rate at which the volume of the note decreases
|
|
||||||
as soon as the note off is given.
|
|
||||||
|
|
||||||
lvl |
|
|
||||||
^ | /\Dr __
|
|
||||||
Sl _| _ / _ \__--- \
|
|
||||||
| / ---__ \ Rr
|
|
||||||
| /Ar Sr \ \
|
|
||||||
| / \\
|
|
||||||
|/___________________\________
|
|
||||||
->time
|
|
||||||
|
|
||||||
The overal volume can also be set to sweep up or down lineairly or
|
|
||||||
exponentially from it's current value. This can be done separately
|
|
||||||
for left and right.
|
|
||||||
|
|
||||||
Relevant SPU registers:
|
|
||||||
-------------------------------------------------------------
|
|
||||||
$1f801xx8 Attack/Decay/Sustain level
|
|
||||||
bit |0f|0e 0d 0c 0b 0a 09 08|07 06 05 04|03 02 01 00|
|
|
||||||
desc.|Am| Ar |Dr |Sl |
|
|
||||||
|
|
||||||
Am 0 Attack mode Linear
|
|
||||||
1 Exponential
|
|
||||||
|
|
||||||
Ar 0-7f attack rate
|
|
||||||
Dr 0-f decay rate
|
|
||||||
Sl 0-f sustain level
|
|
||||||
-------------------------------------------------------------
|
|
||||||
$1f801xxa Sustain rate, Release Rate.
|
|
||||||
bit |0f|0e|0d|0c 0b 0a 09 08 07 06|05|04 03 02 01 00|
|
|
||||||
desc.|Sm|Sd| 0| Sr |Rm|Rr |
|
|
||||||
|
|
||||||
Sm 0 sustain rate mode linear
|
|
||||||
1 exponential
|
|
||||||
Sd 0 sustain rate mode increase
|
|
||||||
1 decrease
|
|
||||||
Sr 0-7f Sustain Rate
|
|
||||||
Rm 0 Linear decrease
|
|
||||||
1 Exponential decrease
|
|
||||||
Rr 0-1f Release Rate
|
|
||||||
|
|
||||||
Note: decay mode is always Expontial decrease, and thus cannot
|
|
||||||
be set.
|
|
||||||
-------------------------------------------------------------
|
|
||||||
$1f801xxc Current ADSR volume
|
|
||||||
bit |0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00|
|
|
||||||
desc.|ADSRvol |
|
|
||||||
|
|
||||||
ADSRvol Returns the current envelope volume when
|
|
||||||
read.
|
|
||||||
-- James' Note: return range: 0 -> 32767
|
|
||||||
|
|
||||||
*** doomed doc extract end ***
|
|
||||||
|
|
||||||
By using a small PSX proggie to visualise the envelope as it was played,
|
|
||||||
the following results for envelope timing were obtained:
|
|
||||||
|
|
||||||
1. Attack rate value (linear mode)
|
|
||||||
|
|
||||||
Attack value range: 0 -> 127
|
|
||||||
|
|
||||||
Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 | | 80 |
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Frames | 11 | 21 | 42 | 84 | 169| 338| 676| |2890|
|
|
||||||
|
|
||||||
Note: frames is no. of PAL frames to reach full volume (100%
|
|
||||||
amplitude)
|
|
||||||
|
|
||||||
Hmm, noticing that the time taken to reach full volume doubles
|
|
||||||
every time we add 4 to our attack value, we know the equation is
|
|
||||||
of form:
|
|
||||||
frames = k * 2 ^ (value / 4)
|
|
||||||
|
|
||||||
(You may ponder about envelope generator hardware at this point,
|
|
||||||
or maybe not... :)
|
|
||||||
|
|
||||||
By substituting some stuff and running some checks, we get:
|
|
||||||
|
|
||||||
k = 0.00257 (close enuf)
|
|
||||||
|
|
||||||
therefore,
|
|
||||||
frames = 0.00257 * 2 ^ (value / 4)
|
|
||||||
If you just happen to be writing an emulator, then you can probably
|
|
||||||
use an equation like:
|
|
||||||
|
|
||||||
%volume_increase_per_tick = 1 / frames
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------
|
|
||||||
Pete:
|
|
||||||
ms=((1<<(value>>2))*514)/10000
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
2. Decay rate value (only has log mode)
|
|
||||||
|
|
||||||
Decay value range: 0 -> 15
|
|
||||||
|
|
||||||
Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
|
||||||
------------------------------------------------
|
|
||||||
frames | | | | | 6 | 12 | 24 | 47 |
|
|
||||||
|
|
||||||
Note: frames here is no. of PAL frames to decay to 50% volume.
|
|
||||||
|
|
||||||
formula: frames = k * 2 ^ (value)
|
|
||||||
|
|
||||||
Substituting, we get: k = 0.00146
|
|
||||||
|
|
||||||
Further info on logarithmic nature:
|
|
||||||
frames to decay to sustain level 3 = 3 * frames to decay to
|
|
||||||
sustain level 9
|
|
||||||
|
|
||||||
Also no. of frames to 25% volume = roughly 1.85 * no. of frames to
|
|
||||||
50% volume.
|
|
||||||
|
|
||||||
Frag it - just use linear approx.
|
|
||||||
|
|
||||||
------------------------------------
|
|
||||||
Pete:
|
|
||||||
ms=((1<<value)*292)/10000
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
3. Sustain rate value (linear mode)
|
|
||||||
|
|
||||||
Sustain rate range: 0 -> 127
|
|
||||||
|
|
||||||
Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 |
|
|
||||||
-------------------------------------------
|
|
||||||
frames | 9 | 19 | 37 | 74 | 147| 293| 587|
|
|
||||||
|
|
||||||
Here, frames = no. of PAL frames for volume amplitude to go from 100%
|
|
||||||
to 0% (or vice-versa).
|
|
||||||
|
|
||||||
Same formula as for attack value, just a different value for k:
|
|
||||||
|
|
||||||
k = 0.00225
|
|
||||||
|
|
||||||
ie: frames = 0.00225 * 2 ^ (value / 4)
|
|
||||||
|
|
||||||
For emulation purposes:
|
|
||||||
|
|
||||||
%volume_increase_or_decrease_per_tick = 1 / frames
|
|
||||||
|
|
||||||
------------------------------------
|
|
||||||
Pete:
|
|
||||||
ms=((1<<(value>>2))*450)/10000
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
4. Release rate (linear mode)
|
|
||||||
|
|
||||||
Release rate range: 0 -> 31
|
|
||||||
|
|
||||||
Value | 13 | 14 | 15 | 16 | 17 |
|
|
||||||
---------------------------------------------------------------
|
|
||||||
frames | 18 | 36 | 73 | 146| 292|
|
|
||||||
|
|
||||||
Here, frames = no. of PAL frames to decay from 100% vol to 0% vol
|
|
||||||
after "note-off" is triggered.
|
|
||||||
|
|
||||||
Formula: frames = k * 2 ^ (value)
|
|
||||||
|
|
||||||
And so: k = 0.00223
|
|
||||||
|
|
||||||
------------------------------------
|
|
||||||
Pete:
|
|
||||||
ms=((1<<value)*446)/10000
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Other notes:
|
|
||||||
|
|
||||||
Log stuff not figured out. You may get some clues from the "Decay rate"
|
|
||||||
stuff above. For emu purposes it may not be important - use linear
|
|
||||||
approx.
|
|
||||||
|
|
||||||
To get timings in millisecs, multiply frames by 20.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- James Higgs 17/6/2000
|
|
||||||
james7780@yahoo.com
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
|
||||||
|
|
||||||
OLD adsr mixing according to james' rules... has to be called
|
|
||||||
every one millisecond
|
|
||||||
|
|
||||||
|
|
||||||
long v,v2,lT,l1,l2,l3;
|
|
||||||
|
|
||||||
if(s_chan[ch].bStop) // psx wants to stop? -> release phase
|
|
||||||
{
|
|
||||||
if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
|
|
||||||
{
|
|
||||||
if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
|
|
||||||
{
|
|
||||||
s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime;
|
|
||||||
s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume;
|
|
||||||
s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
|
|
||||||
(s_chan[ch].ADSR.ReleaseTime*
|
|
||||||
s_chan[ch].ADSR.ReleaseVol)/1024;
|
|
||||||
}
|
|
||||||
// -> NO release exp mode used (yet)
|
|
||||||
v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume
|
|
||||||
lT=s_chan[ch].ADSR.lTime- // -> how much time is past?
|
|
||||||
s_chan[ch].ADSR.ReleaseStartTime;
|
|
||||||
l1=s_chan[ch].ADSR.ReleaseTime;
|
|
||||||
|
|
||||||
if(lT<l1) // -> we still have to release
|
|
||||||
{
|
|
||||||
v=v-((v*lT)/l1); // --> calc new volume
|
|
||||||
}
|
|
||||||
else // -> release is over: now really stop that sample
|
|
||||||
{v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
|
|
||||||
}
|
|
||||||
else // -> release IS 0: release at once
|
|
||||||
{
|
|
||||||
v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{//--------------------------------------------------// not in release phase:
|
|
||||||
v=1024;
|
|
||||||
lT=s_chan[ch].ADSR.lTime;
|
|
||||||
l1=s_chan[ch].ADSR.AttackTime;
|
|
||||||
|
|
||||||
if(lT<l1) // attack
|
|
||||||
{ // no exp mode used (yet)
|
|
||||||
// if(s_chan[ch].ADSR.AttackModeExp)
|
|
||||||
// {
|
|
||||||
// v=(v*lT)/l1;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
{
|
|
||||||
v=(v*lT)/l1;
|
|
||||||
}
|
|
||||||
if(v==0) v=1;
|
|
||||||
}
|
|
||||||
else // decay
|
|
||||||
{ // should be exp, but who cares? ;)
|
|
||||||
l2=s_chan[ch].ADSR.DecayTime;
|
|
||||||
v2=s_chan[ch].ADSR.SustainLevel;
|
|
||||||
|
|
||||||
lT-=l1;
|
|
||||||
if(lT<l2)
|
|
||||||
{
|
|
||||||
v-=(((v-v2)*lT)/l2);
|
|
||||||
}
|
|
||||||
else // sustain
|
|
||||||
{ // no exp mode used (yet)
|
|
||||||
l3=s_chan[ch].ADSR.SustainTime;
|
|
||||||
lT-=l2;
|
|
||||||
if(s_chan[ch].ADSR.SustainModeDec>0)
|
|
||||||
{
|
|
||||||
if(l3!=0) v2+=((v-v2)*lT)/l3;
|
|
||||||
else v2=v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(l3!=0) v2-=(v2*lT)/l3;
|
|
||||||
else v2=v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(v2>v) v2=v;
|
|
||||||
if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
|
|
||||||
|
|
||||||
v=v2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
// ok, done for this channel, so increase time
|
|
||||||
|
|
||||||
s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
|
|
||||||
|
|
||||||
if(v>1024) v=1024; // adjust volume
|
|
||||||
if(v<0) v=0;
|
|
||||||
s_chan[ch].ADSR.lVolume=v; // store act volume
|
|
||||||
|
|
||||||
return v; // return the volume factor
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
Neill Corlett
|
|
||||||
Playstation SPU envelope timing notes
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
This is preliminary. This may be wrong. But the model described herein fits
|
|
||||||
all of my experimental data, and it's just simple enough to sound right.
|
|
||||||
|
|
||||||
ADSR envelope level ranges from 0x00000000 to 0x7FFFFFFF internally.
|
|
||||||
The value returned by channel reg 0xC is (envelope_level>>16).
|
|
||||||
|
|
||||||
Each sample, an increment or decrement value will be added to or
|
|
||||||
subtracted from this envelope level.
|
|
||||||
|
|
||||||
Create the rate log table. The values double every 4 entries.
|
|
||||||
entry #0 = 4
|
|
||||||
|
|
||||||
4, 5, 6, 7,
|
|
||||||
8,10,12,14,
|
|
||||||
16,20,24,28, ...
|
|
||||||
|
|
||||||
entry #40 = 4096...
|
|
||||||
entry #44 = 8192...
|
|
||||||
entry #48 = 16384...
|
|
||||||
entry #52 = 32768...
|
|
||||||
entry #56 = 65536...
|
|
||||||
|
|
||||||
increments and decrements are in terms of ratelogtable[n]
|
|
||||||
n may exceed the table bounds (plan on n being between -32 and 127).
|
|
||||||
table values are all clipped between 0x00000000 and 0x3FFFFFFF
|
|
||||||
|
|
||||||
when you "voice on", the envelope is always fully reset.
|
|
||||||
(yes, it may click. the real thing does this too.)
|
|
||||||
|
|
||||||
envelope level begins at zero.
|
|
||||||
|
|
||||||
each state happens for at least 1 cycle
|
|
||||||
(transitions are not instantaneous)
|
|
||||||
this may result in some oddness: if the decay rate is uberfast, it will cut
|
|
||||||
the envelope from full down to half in one sample, potentially skipping over
|
|
||||||
the sustain level
|
|
||||||
|
|
||||||
ATTACK
|
|
||||||
------
|
|
||||||
- if the envelope level has overflowed past the max, clip to 0x7FFFFFFF and
|
|
||||||
proceed to DECAY.
|
|
||||||
|
|
||||||
Linear attack mode:
|
|
||||||
- line extends upward to 0x7FFFFFFF
|
|
||||||
- increment per sample is ratelogtable[(Ar^0x7F)-0x10]
|
|
||||||
|
|
||||||
Logarithmic attack mode:
|
|
||||||
if envelope_level < 0x60000000:
|
|
||||||
- line extends upward to 0x60000000
|
|
||||||
- increment per sample is ratelogtable[(Ar^0x7F)-0x10]
|
|
||||||
else:
|
|
||||||
- line extends upward to 0x7FFFFFFF
|
|
||||||
- increment per sample is ratelogtable[(Ar^0x7F)-0x18]
|
|
||||||
|
|
||||||
DECAY
|
|
||||||
-----
|
|
||||||
- if ((envelope_level>>27)&0xF) <= Sl, proceed to SUSTAIN.
|
|
||||||
Do not clip to the sustain level.
|
|
||||||
- current line ends at (envelope_level & 0x07FFFFFF)
|
|
||||||
- decrement per sample depends on (envelope_level>>28)&0x7
|
|
||||||
0: ratelogtable[(4*(Dr^0x1F))-0x18+0]
|
|
||||||
1: ratelogtable[(4*(Dr^0x1F))-0x18+4]
|
|
||||||
2: ratelogtable[(4*(Dr^0x1F))-0x18+6]
|
|
||||||
3: ratelogtable[(4*(Dr^0x1F))-0x18+8]
|
|
||||||
4: ratelogtable[(4*(Dr^0x1F))-0x18+9]
|
|
||||||
5: ratelogtable[(4*(Dr^0x1F))-0x18+10]
|
|
||||||
6: ratelogtable[(4*(Dr^0x1F))-0x18+11]
|
|
||||||
7: ratelogtable[(4*(Dr^0x1F))-0x18+12]
|
|
||||||
(note that this is the same as the release rate formula, except that
|
|
||||||
decay rates 10-1F aren't possible... those would be slower in theory)
|
|
||||||
|
|
||||||
SUSTAIN
|
|
||||||
-------
|
|
||||||
- no terminating condition except for voice off
|
|
||||||
- Sd=0 (increase) behavior is identical to ATTACK for both log and linear.
|
|
||||||
- Sd=1 (decrease) behavior:
|
|
||||||
Linear sustain decrease:
|
|
||||||
- line extends to 0x00000000
|
|
||||||
- decrement per sample is ratelogtable[(Sr^0x7F)-0x0F]
|
|
||||||
Logarithmic sustain decrease:
|
|
||||||
- current line ends at (envelope_level & 0x07FFFFFF)
|
|
||||||
- decrement per sample depends on (envelope_level>>28)&0x7
|
|
||||||
0: ratelogtable[(Sr^0x7F)-0x1B+0]
|
|
||||||
1: ratelogtable[(Sr^0x7F)-0x1B+4]
|
|
||||||
2: ratelogtable[(Sr^0x7F)-0x1B+6]
|
|
||||||
3: ratelogtable[(Sr^0x7F)-0x1B+8]
|
|
||||||
4: ratelogtable[(Sr^0x7F)-0x1B+9]
|
|
||||||
5: ratelogtable[(Sr^0x7F)-0x1B+10]
|
|
||||||
6: ratelogtable[(Sr^0x7F)-0x1B+11]
|
|
||||||
7: ratelogtable[(Sr^0x7F)-0x1B+12]
|
|
||||||
|
|
||||||
RELEASE
|
|
||||||
-------
|
|
||||||
- if the envelope level has overflowed to negative, clip to 0 and QUIT.
|
|
||||||
|
|
||||||
Linear release mode:
|
|
||||||
- line extends to 0x00000000
|
|
||||||
- decrement per sample is ratelogtable[(4*(Rr^0x1F))-0x0C]
|
|
||||||
|
|
||||||
Logarithmic release mode:
|
|
||||||
- line extends to (envelope_level & 0x0FFFFFFF)
|
|
||||||
- decrement per sample depends on (envelope_level>>28)&0x7
|
|
||||||
0: ratelogtable[(4*(Rr^0x1F))-0x18+0]
|
|
||||||
1: ratelogtable[(4*(Rr^0x1F))-0x18+4]
|
|
||||||
2: ratelogtable[(4*(Rr^0x1F))-0x18+6]
|
|
||||||
3: ratelogtable[(4*(Rr^0x1F))-0x18+8]
|
|
||||||
4: ratelogtable[(4*(Rr^0x1F))-0x18+9]
|
|
||||||
5: ratelogtable[(4*(Rr^0x1F))-0x18+10]
|
|
||||||
6: ratelogtable[(4*(Rr^0x1F))-0x18+11]
|
|
||||||
7: ratelogtable[(4*(Rr^0x1F))-0x18+12]
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
adsr.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
INLINE void StartADSR(int ch);
|
|
||||||
INLINE int MixADSR(int ch);
|
|
|
@ -1,206 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
alsa.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sat Mar 01 2003
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/03/02 - linuzappz
|
|
||||||
// - fixed XRUN behavior
|
|
||||||
//
|
|
||||||
// 2003/03/01 - linuzappz
|
|
||||||
// - created
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_OSS
|
|
||||||
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
#ifndef _WINDOWS
|
|
||||||
|
|
||||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
|
||||||
#define ALSA_PCM_NEW_SW_PARAMS_API
|
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// small linux time helper... only used for watchdog
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
unsigned long timeGetTime()
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, 0); // well, maybe there are better ways
|
|
||||||
return tv.tv_sec * 1000 + tv.tv_usec/1000; // to do that, but at least it works
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// oss globals
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define ALSA_MEM_DEF
|
|
||||||
#include "alsa.h"
|
|
||||||
static snd_pcm_t *handle = NULL;
|
|
||||||
static snd_pcm_uframes_t buffer_size;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// SETUP SOUND
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SetupSound(void)
|
|
||||||
{
|
|
||||||
snd_pcm_hw_params_t *hwparams;
|
|
||||||
snd_pcm_sw_params_t *swparams;
|
|
||||||
snd_pcm_status_t *status;
|
|
||||||
int pspeed;
|
|
||||||
int pchannels;
|
|
||||||
int format;
|
|
||||||
int buffer_time;
|
|
||||||
int period_time;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if(iDisStereo) pchannels=1;
|
|
||||||
else pchannels=2;
|
|
||||||
|
|
||||||
pspeed=48000;
|
|
||||||
format=SND_PCM_FORMAT_S16_LE;
|
|
||||||
buffer_time=500000;
|
|
||||||
period_time=buffer_time/4;
|
|
||||||
|
|
||||||
if((err=snd_pcm_open(&handle, "default",
|
|
||||||
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))<0)
|
|
||||||
{
|
|
||||||
printf("Audio open error: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_nonblock(handle, 0))<0)
|
|
||||||
{
|
|
||||||
printf("Can't set blocking moded: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snd_pcm_hw_params_alloca(&hwparams);
|
|
||||||
snd_pcm_sw_params_alloca(&swparams);
|
|
||||||
if((err=snd_pcm_hw_params_any(handle, hwparams))<0)
|
|
||||||
{
|
|
||||||
printf("Broken configuration for this PCM: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED))<0)
|
|
||||||
{
|
|
||||||
printf("Access type not available: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params_set_format(handle, hwparams, format))<0)
|
|
||||||
{
|
|
||||||
printf("Sample format not available: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params_set_channels(handle, hwparams, pchannels))<0)
|
|
||||||
{
|
|
||||||
printf("Channels count not available: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params_set_rate_near(handle, hwparams, &pspeed, 0))<0)
|
|
||||||
{
|
|
||||||
printf("Rate not available: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0))<0)
|
|
||||||
{
|
|
||||||
printf("Buffer time error: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0))<0)
|
|
||||||
{
|
|
||||||
printf("Period time error: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((err=snd_pcm_hw_params(handle, hwparams))<0)
|
|
||||||
{
|
|
||||||
printf("Unable to install hw params: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snd_pcm_status_alloca(&status);
|
|
||||||
if((err=snd_pcm_status(handle, status))<0)
|
|
||||||
{
|
|
||||||
printf("Unable to get status: %s\n", snd_strerror(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_size=snd_pcm_status_get_avail(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// REMOVE SOUND
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void RemoveSound(void)
|
|
||||||
{
|
|
||||||
if(handle != NULL)
|
|
||||||
{
|
|
||||||
snd_pcm_drop(handle);
|
|
||||||
snd_pcm_close(handle);
|
|
||||||
handle = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// GET BYTES BUFFERED
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
unsigned long SoundGetBytesBuffered(void)
|
|
||||||
{
|
|
||||||
unsigned long l;
|
|
||||||
|
|
||||||
if(handle == NULL) // failed to open?
|
|
||||||
return SOUNDSIZE;
|
|
||||||
l = snd_pcm_avail_update(handle);
|
|
||||||
if(l<0) return 0;
|
|
||||||
if(l<buffer_size/2) // can we write in at least the half of fragments?
|
|
||||||
l=SOUNDSIZE; // -> no? wait
|
|
||||||
else l=0; // -> else go on
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// FEED SOUND DATA
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SoundFeedVoiceData(unsigned char* pSound,long lBytes)
|
|
||||||
{
|
|
||||||
if(handle == NULL) return;
|
|
||||||
|
|
||||||
if(snd_pcm_state(handle) == SND_PCM_STATE_XRUN)
|
|
||||||
snd_pcm_prepare(handle);
|
|
||||||
snd_pcm_writei(handle,pSound,
|
|
||||||
iDisStereo == 1 ? lBytes/2 : lBytes/4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,30 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
alsa.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Sat Mar 01 2003
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _ALSA_SOUND_H
|
|
||||||
#define _ALSA_SOUND_H
|
|
||||||
|
|
||||||
#ifdef ALSA_MEM_DEF
|
|
||||||
#define ALSA_MEM_EXTERN
|
|
||||||
#else
|
|
||||||
#define ALSA_MEM_EXTERN extern
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ALSA_MEM_EXTERN int sound_buffer_size;
|
|
||||||
|
|
||||||
#endif // _ALSA_SOUND_H
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
curdir=`pwd`
|
|
||||||
|
|
||||||
echo ------------------
|
|
||||||
echo Building PeopsSPU2
|
|
||||||
echo ------------------
|
|
||||||
|
|
||||||
make $@
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -s libspu2Peops*.so* ]
|
|
||||||
then
|
|
||||||
cp libspu2Peops*.so* ${PCSX2PLUGINS}
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,256 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cfg.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2003/06/07 - Pete
|
|
||||||
// - added Linux NOTHREADLIB define
|
|
||||||
//
|
|
||||||
// 2003/02/28 - Pete
|
|
||||||
// - added option for kode54's interpolation and linuzappz's mono mode
|
|
||||||
//
|
|
||||||
// 2003/01/19 - Pete
|
|
||||||
// - added Neill's reverb
|
|
||||||
//
|
|
||||||
// 2002/08/04 - Pete
|
|
||||||
// - small linux bug fix: now the cfg file can be in the main emu directory as well
|
|
||||||
//
|
|
||||||
// 2002/06/08 - linuzappz
|
|
||||||
// - Added combo str for SPUasync, and MAXMODE is now defined as 2
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_CFG
|
|
||||||
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WINDOWS CONFIG/ABOUT HANDLING
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// simple about dlg handler
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch(uMsg)
|
|
||||||
{
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
|
||||||
switch(LOWORD(wParam))
|
|
||||||
{case IDOK: EndDialog(hW,TRUE);return TRUE;}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// READ CONFIG: from win registry
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// timer mode 2 (spuupdate sync mode) can be enabled for windows
|
|
||||||
// by setting MAXMODE to 2.
|
|
||||||
// Attention: that mode is not much tested, maybe the dsound buffers
|
|
||||||
// need to get adjusted to use that mode safely. Also please note:
|
|
||||||
// sync sound updates will _always_ cause glitches, if the system is
|
|
||||||
// busy by, for example, long lasting cdrom accesses. OK, you have
|
|
||||||
// be warned :)
|
|
||||||
|
|
||||||
#define MAXMODE 2
|
|
||||||
//#define MAXMODE 1
|
|
||||||
|
|
||||||
void ReadConfig(void)
|
|
||||||
{
|
|
||||||
HKEY myKey;
|
|
||||||
DWORD temp;
|
|
||||||
DWORD type;
|
|
||||||
DWORD size;
|
|
||||||
// init vars
|
|
||||||
iVolume=3;
|
|
||||||
iDebugMode=0;
|
|
||||||
iRecordMode=0;
|
|
||||||
iUseReverb=0;
|
|
||||||
iUseInterpolation=2;
|
|
||||||
iUseTimer = 2;
|
|
||||||
|
|
||||||
if(RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\PS2Eplugin\\SPU2\\PeopsSound",0,KEY_ALL_ACCESS,&myKey)==ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"Volume",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iVolume=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"DebugMode",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iDebugMode=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"RecordMode",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iRecordMode=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseReverb",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseReverb=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseInterpolation",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseInterpolation=(int)temp;
|
|
||||||
size = 4;
|
|
||||||
if(RegQueryValueEx(myKey,"UseTimer",0,&type,(LPBYTE)&temp,&size)==ERROR_SUCCESS)
|
|
||||||
iUseTimer=(int)temp;
|
|
||||||
|
|
||||||
|
|
||||||
RegCloseKey(myKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(iVolume<1) iVolume=1;
|
|
||||||
if(iVolume>5) iVolume=5;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WRITE CONFIG: in win registry
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void WriteConfig(void)
|
|
||||||
{
|
|
||||||
HKEY myKey;
|
|
||||||
DWORD myDisp;
|
|
||||||
DWORD temp;
|
|
||||||
|
|
||||||
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\PS2Eplugin\\SPU2\\PeopsSound",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&myKey,&myDisp);
|
|
||||||
temp=iVolume;
|
|
||||||
RegSetValueEx(myKey,"Volume",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iDebugMode;
|
|
||||||
RegSetValueEx(myKey,"DebugMode",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iRecordMode;
|
|
||||||
RegSetValueEx(myKey,"RecordMode",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseReverb;
|
|
||||||
RegSetValueEx(myKey,"UseReverb",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseInterpolation;
|
|
||||||
RegSetValueEx(myKey,"UseInterpolation",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
temp=iUseTimer;
|
|
||||||
RegSetValueEx(myKey,"UseTimer",0,REG_DWORD,(LPBYTE) &temp,sizeof(temp));
|
|
||||||
RegCloseKey(myKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// INIT WIN CFG DIALOG
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL OnInitDSoundDialog(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC;
|
|
||||||
|
|
||||||
ReadConfig();
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_VOLUME);
|
|
||||||
ComboBox_AddString(hWC, "0: Mute");
|
|
||||||
ComboBox_AddString(hWC, "1: low");
|
|
||||||
ComboBox_AddString(hWC, "2: medium");
|
|
||||||
ComboBox_AddString(hWC, "3: loud");
|
|
||||||
ComboBox_AddString(hWC, "4: loudest");
|
|
||||||
ComboBox_SetCurSel(hWC,5-iVolume);
|
|
||||||
if(iDebugMode) CheckDlgButton(hW,IDC_DEBUGMODE,TRUE);
|
|
||||||
if(iRecordMode) CheckDlgButton(hW,IDC_RECORDMODE,TRUE);
|
|
||||||
if(iUseTimer==0) CheckDlgButton(hW,IDC_TIMER,TRUE);
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_USEREVERB);
|
|
||||||
ComboBox_AddString(hWC, "0: No reverb (fastest)");
|
|
||||||
ComboBox_AddString(hWC, "1: SPU2 reverb (may be buggy, not tested yet)");
|
|
||||||
ComboBox_SetCurSel(hWC,iUseReverb);
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_INTERPOL);
|
|
||||||
ComboBox_AddString(hWC, "0: None (fastest)");
|
|
||||||
ComboBox_AddString(hWC, "1: Simple interpolation");
|
|
||||||
ComboBox_AddString(hWC, "2: Gaussian interpolation (good quality)");
|
|
||||||
ComboBox_AddString(hWC, "3: Cubic interpolation (better treble)");
|
|
||||||
ComboBox_SetCurSel(hWC,iUseInterpolation);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WIN CFG DLG OK
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void OnDSoundOK(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWC;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_TIMER))
|
|
||||||
iUseTimer=0; else iUseTimer=2;
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_VOLUME);
|
|
||||||
iVolume=5-ComboBox_GetCurSel(hWC);
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_USEREVERB);
|
|
||||||
iUseReverb=ComboBox_GetCurSel(hWC);
|
|
||||||
|
|
||||||
hWC=GetDlgItem(hW,IDC_INTERPOL);
|
|
||||||
iUseInterpolation=ComboBox_GetCurSel(hWC);
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_DEBUGMODE))
|
|
||||||
iDebugMode=1; else iDebugMode=0;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_RECORDMODE))
|
|
||||||
iRecordMode=1; else iRecordMode=0;
|
|
||||||
|
|
||||||
WriteConfig(); // write registry
|
|
||||||
|
|
||||||
EndDialog(hW,TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WIN CFG DLG CANCEL
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void OnDSoundCancel(HWND hW)
|
|
||||||
{
|
|
||||||
EndDialog(hW,FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WIN CFG PROC
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL CALLBACK DSoundDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch(uMsg)
|
|
||||||
{
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
return OnInitDSoundDialog(hW);
|
|
||||||
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
|
||||||
switch(LOWORD(wParam))
|
|
||||||
{
|
|
||||||
case IDCANCEL: OnDSoundCancel(hW);return TRUE;
|
|
||||||
case IDOK: OnDSoundOK(hW); return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
cfg.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
|
|
||||||
void ReadConfig(void);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
BOOL CALLBACK DSoundDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
#else
|
|
||||||
void StartCfgTool(char * pCmdLine);
|
|
||||||
#endif
|
|
|
@ -1,3 +0,0 @@
|
||||||
del *.o
|
|
||||||
del *.c~
|
|
||||||
del *.h~
|
|
|
@ -1,442 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
debug.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/12/25 - Pete
|
|
||||||
// - update mute checkboxes if core selection changes
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2003/01/06 - Pete
|
|
||||||
// - added Neil's ADSR timings
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_DEBUG
|
|
||||||
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WINDOWS DEBUG DIALOG HANDLING
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
//#define SMALLDEBUG
|
|
||||||
//#include <dbgout.h>
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// display debug infos
|
|
||||||
|
|
||||||
const COLORREF crStreamCol[]={
|
|
||||||
RGB( 0, 0, 0),
|
|
||||||
RGB(255,255,255),
|
|
||||||
RGB(128, 0,128),
|
|
||||||
RGB( 0,128, 0),
|
|
||||||
RGB( 0, 0,255),
|
|
||||||
RGB(255, 0, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
const COLORREF crAdsrCol[] ={
|
|
||||||
RGB( 0, 0, 0),
|
|
||||||
RGB(255, 0, 0),
|
|
||||||
RGB( 0,255, 0),
|
|
||||||
RGB(255, 0,255),
|
|
||||||
RGB( 0, 0,255),
|
|
||||||
RGB( 0, 0, 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
HBRUSH hBStream[6]; // brushes for stream lines
|
|
||||||
HPEN hPAdsr[6]; // pens for adsr lines
|
|
||||||
int iSelChannel=0; // user selected channel
|
|
||||||
int iCoreOffset=0;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// display the sound data waves: no subclassing used, so the
|
|
||||||
// area will not be redrawn... but faster that way, and good enuff
|
|
||||||
// for debugging purposes
|
|
||||||
|
|
||||||
void DisplayStreamInfos(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWS=GetDlgItem(hW,IDC_SAREA);
|
|
||||||
HDC hdc;RECT r;HBRUSH hBO;int ch,dy,i,j,id;
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
|
|
||||||
GetClientRect(hWS,&r); // get size of stream display
|
|
||||||
hdc=GetDC(hWS); // device context
|
|
||||||
r.right--; // leave the right border intact
|
|
||||||
ScrollDC(hdc,-1,0,&r,&r,NULL,NULL); // scroll one pixel to the left
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
|
|
||||||
hBO=SelectObject(hdc,hBStream[0]); // clean the right border
|
|
||||||
PatBlt(hdc,r.right-1,0,1,r.bottom,PATCOPY);
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
|
|
||||||
dy=r.bottom/HLFCHAN; // size of one channel area
|
|
||||||
|
|
||||||
for(ch=0;ch<HLFCHAN;ch++) // loop the channels
|
|
||||||
{
|
|
||||||
if(s_chan[ch+iCoreOffset].bOn) // channel is on?
|
|
||||||
{
|
|
||||||
if(s_chan[ch+iCoreOffset].iIrqDone)
|
|
||||||
{
|
|
||||||
s_chan[ch+iCoreOffset].iIrqDone=0;
|
|
||||||
PatBlt(hdc,r.right-1,ch*r.bottom/HLFCHAN,
|
|
||||||
1,dy,BLACKNESS);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
j=s_chan[ch+iCoreOffset].sval;if(j<0) j=-j; // -> get one channel data (-32k ... 32k)
|
|
||||||
j=(dy*j)/33768; if(j==0) j=1; // -> adjust to display coords
|
|
||||||
i=(dy/2)+(ch*r.bottom/HLFCHAN)-j/2; // -> position where to paint it
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (s_chan[ch+iCoreOffset].iMute) id=1; // -> get color id
|
|
||||||
else if(s_chan[ch+iCoreOffset].bNoise) id=2;
|
|
||||||
else if(s_chan[ch+iCoreOffset].bFMod==2) id=3;
|
|
||||||
else if(s_chan[ch+iCoreOffset].bFMod==1) id=4;
|
|
||||||
else id=5;
|
|
||||||
|
|
||||||
SelectObject(hdc,hBStream[id]); // -> select the brush
|
|
||||||
PatBlt(hdc,r.right-1,i,1,j,PATCOPY); // -> paint the value line
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ch) SetPixel(hdc,r.right-1, // -> not first line?
|
|
||||||
ch*r.bottom/HLFCHAN,RGB(0,0,0)); // --> draw the line (one dot scrolled to the left)
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
|
|
||||||
SelectObject(hdc,hBO); // repair brush
|
|
||||||
|
|
||||||
ReleaseDC(hWS,hdc); // release context
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// display adsr lines: also no subclassing for repainting used
|
|
||||||
|
|
||||||
void DisplayADSRInfos(HWND hW)
|
|
||||||
{
|
|
||||||
HWND hWS=GetDlgItem(hW,IDC_ADSR);
|
|
||||||
HDC hdc;RECT r;HBRUSH hBO;char szB[16];
|
|
||||||
int ch=iSelChannel+iCoreOffset,dx,dy,dm,dn,ia,id,is,ir;
|
|
||||||
|
|
||||||
//----------------------------------------------------// get display size
|
|
||||||
|
|
||||||
GetClientRect(hWS,&r);
|
|
||||||
hdc=GetDC(hWS);
|
|
||||||
|
|
||||||
//----------------------------------------------------// clean the area
|
|
||||||
|
|
||||||
hBO=SelectObject(hdc,hBStream[0]);
|
|
||||||
PatBlt(hdc,0,0,r.right,r.bottom,PATCOPY);
|
|
||||||
r.left++;r.right-=2;r.top++;r.bottom-=2; // shrink the display rect for better optics
|
|
||||||
|
|
||||||
//----------------------------------------------------//
|
|
||||||
|
|
||||||
ia=min(s_chan[ch].ADSR.AttackTime,10000); // get adsr, but limit it for drawing
|
|
||||||
id=min(s_chan[ch].ADSR.DecayTime,10000);
|
|
||||||
is=min(s_chan[ch].ADSR.SustainTime,10000);
|
|
||||||
ir=min(s_chan[ch].ADSR.ReleaseTime,10000);
|
|
||||||
|
|
||||||
dx=ia+id+is+ir; // get the dx in (limited) adsr units
|
|
||||||
|
|
||||||
// set the real values to the info statics
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR1,s_chan[ch].ADSRX.AttackRate,FALSE);
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR2,s_chan[ch].ADSRX.DecayRate,FALSE);
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR3,s_chan[ch].ADSRX.SustainRate,FALSE);
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR4,s_chan[ch].ADSRX.ReleaseRate,FALSE);
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR5,s_chan[ch].ADSRX.SustainLevel,FALSE);
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR6,s_chan[ch].ADSRX.SustainIncrease,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_SADSR7,s_chan[ch].ADSRX.lVolume,TRUE);
|
|
||||||
wsprintf(szB,"%08lX",s_chan[ch].ADSRX.EnvelopeVol);
|
|
||||||
SetDlgItemText(hW,IDC_SADSR8,szB);
|
|
||||||
|
|
||||||
if(dx) // something to draw?
|
|
||||||
{
|
|
||||||
HPEN hPO=SelectObject(hdc,hPAdsr[1]); // sel A pen
|
|
||||||
dn=r.left;
|
|
||||||
MoveToEx(hdc,dn,r.bottom,NULL); // move to bottom left corner
|
|
||||||
|
|
||||||
dn+=(ia*r.right)/dx; // calc A x line pos
|
|
||||||
LineTo(hdc,dn,r.top); // line to AxPos,top
|
|
||||||
|
|
||||||
SelectObject(hdc,hPAdsr[2]); // sel D pen
|
|
||||||
dn+=(id*r.right)/dx; // calc D x line pos
|
|
||||||
dy=r.top+((1024-s_chan[ch].ADSR.SustainLevel)* // calc the D y pos
|
|
||||||
r.bottom)/1024; // (our S level is ranged from 0 to 1024)
|
|
||||||
LineTo(hdc,dn,dy); // line to DxPos,SLevel
|
|
||||||
|
|
||||||
SelectObject(hdc,hPAdsr[3]); // sel S pen
|
|
||||||
if(s_chan[ch].ADSR.SustainTime>10000)
|
|
||||||
dm=1; // we have to fake the S values... S will
|
|
||||||
else // inc/decrease until channel stop...
|
|
||||||
if(s_chan[ch].ADSR.SustainTime==0)
|
|
||||||
dm=0; // we dunno here when this will happen,
|
|
||||||
else
|
|
||||||
dm=21-(((s_chan[ch].ADSR.SustainTime/500))); // so we do some more or less angled line,
|
|
||||||
dy=dy-(s_chan[ch].ADSR.SustainModeDec*dm); // roughly depending on the S time
|
|
||||||
if(dy>r.bottom) dy=r.bottom;
|
|
||||||
if(dy<r.top) dy=r.top;
|
|
||||||
dn+=(is*r.right)/dx;
|
|
||||||
LineTo(hdc,dn,dy); // line to SxPos, fake end volume level
|
|
||||||
|
|
||||||
SelectObject(hdc,hPAdsr[4]); // sel R pen
|
|
||||||
dn+=(ir*r.right)/dx; // calc R x line pos
|
|
||||||
LineTo(hdc,dn,r.bottom); // line to RxPos, bottom right y
|
|
||||||
|
|
||||||
SelectObject(hdc,hPO); // repair pen
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectObject(hdc,hBO); // repair brush
|
|
||||||
ReleaseDC(hWS,hdc); // release context
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DisplayChannelInfos(HWND hW)
|
|
||||||
{
|
|
||||||
int ch=iSelChannel+iCoreOffset;char szB[16];
|
|
||||||
|
|
||||||
// channel infos
|
|
||||||
SetDlgItemInt(hW,IDC_CI1,s_chan[ch].bOn,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_CI2,s_chan[ch].bStop,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_CI3,s_chan[ch].bNoise,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_CI4,s_chan[ch].bFMod,TRUE);
|
|
||||||
wsprintf(szB,"L%d R%d",s_chan[ch].bReverbL,s_chan[ch].bReverbR);
|
|
||||||
SetDlgItemText(hW,IDC_CI5,szB);
|
|
||||||
SetDlgItemInt(hW,IDC_CI6,s_chan[ch].bRVBActive,TRUE);
|
|
||||||
wsprintf(szB,"%08lX",rvb[iCoreOffset/24].StartAddr);
|
|
||||||
SetDlgItemText(hW,IDC_CI7,szB);
|
|
||||||
wsprintf(szB,"%08lX",rvb[iCoreOffset/24].EndAddr);
|
|
||||||
SetDlgItemText(hW,IDC_CI8,szB);
|
|
||||||
wsprintf(szB,"%08lX",rvb[iCoreOffset/24].CurrAddr);
|
|
||||||
SetDlgItemText(hW,IDC_CI9,szB);
|
|
||||||
|
|
||||||
wsprintf(szB,"%08lX",((unsigned long)s_chan[ch].pStart-(unsigned long)spuMemC)>>1);
|
|
||||||
SetDlgItemText(hW,IDC_CI10,szB);
|
|
||||||
if(s_chan[ch].pCurr==(unsigned char *)-1)
|
|
||||||
SetDlgItemText(hW,IDC_CI11,"FFFFFFFF");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wsprintf(szB,"%08lX",((unsigned long)s_chan[ch].pCurr-(unsigned long)spuMemC)>>1);
|
|
||||||
SetDlgItemText(hW,IDC_CI11,szB);
|
|
||||||
}
|
|
||||||
|
|
||||||
wsprintf(szB,"%08lX",((unsigned long)s_chan[ch].pLoop-(unsigned long)spuMemC)>>1);
|
|
||||||
SetDlgItemText(hW,IDC_CI12,szB);
|
|
||||||
SetDlgItemInt(hW,IDC_CI13,s_chan[ch].iRightVolume,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_CI14,s_chan[ch].iLeftVolume,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_CI15,s_chan[ch].iActFreq,TRUE);
|
|
||||||
SetDlgItemInt(hW,IDC_CI16,s_chan[ch].iUsedFreq,TRUE);
|
|
||||||
|
|
||||||
// wsprintf(szB,"%04x",s_chan[ch].iRightVolRaw);
|
|
||||||
wsprintf(szB,"R%d",s_chan[ch].bVolumeR);
|
|
||||||
SetDlgItemText(hW,IDC_CI17,szB);
|
|
||||||
// wsprintf(szB,"%04x",s_chan[ch].iLeftVolRaw);
|
|
||||||
wsprintf(szB,"L%d",s_chan[ch].bVolumeL);
|
|
||||||
SetDlgItemText(hW,IDC_CI18,szB);
|
|
||||||
|
|
||||||
wsprintf(szB,"%08lX",s_chan[ch].iNextAdr);
|
|
||||||
SetDlgItemText(hW,IDC_CI19,szB);
|
|
||||||
|
|
||||||
// generic infos
|
|
||||||
/*if(pSpuIrq[ch]==0)
|
|
||||||
SetDlgItemText(hW,IDC_STA1,"FFFFFFFF");
|
|
||||||
else
|
|
||||||
{*/
|
|
||||||
wsprintf(szB,"%08lX",((unsigned long)pSpuIrq[ch/24]-(unsigned long)spuMemC)>>1);
|
|
||||||
SetDlgItemText(hW,IDC_STA1,szB);
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
wsprintf(szB,"%04X",spuCtrl2[ch/24]);
|
|
||||||
SetDlgItemText(hW,IDC_STA2,szB);
|
|
||||||
wsprintf(szB,"%04X",spuStat2[ch/24]);
|
|
||||||
SetDlgItemText(hW,IDC_STA3,szB);
|
|
||||||
|
|
||||||
wsprintf(szB,"%08lX",spuAddr2[ch/24]);
|
|
||||||
SetDlgItemText(hW,IDC_STA4,szB);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// display everything (called in dialog timer for value refreshing)
|
|
||||||
|
|
||||||
void DisplayDebugInfos(HWND hW)
|
|
||||||
{
|
|
||||||
DisplayStreamInfos(hW);
|
|
||||||
DisplayADSRInfos(hW);
|
|
||||||
DisplayChannelInfos(hW);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2write(unsigned long reg, unsigned short val);
|
|
||||||
EXPORT_GCC unsigned short CALLBACK SPU2read(unsigned long reg);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// main debug dlg handler
|
|
||||||
|
|
||||||
char old_buffer[128];
|
|
||||||
int iBuffRepeats=0;
|
|
||||||
|
|
||||||
BOOL CALLBACK DebugDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch(uMsg)
|
|
||||||
{
|
|
||||||
//--------------------------------------------------// init
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ShowCursor(TRUE); // mmm... who is hiding it? main emu? tsts
|
|
||||||
iSelChannel=0; // sel first channel
|
|
||||||
iCoreOffset=0;
|
|
||||||
CheckRadioButton(hW,IDC_CHAN1,IDC_CHAN24,IDC_CHAN1);
|
|
||||||
CheckRadioButton(hW,IDC_CORE1,IDC_CORE2,IDC_CORE1);
|
|
||||||
|
|
||||||
memset(old_buffer,0,128);
|
|
||||||
// create brushes/pens
|
|
||||||
hBStream[0]=CreateSolidBrush(GetSysColor(COLOR_3DFACE));
|
|
||||||
hPAdsr[0]=CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DFACE));
|
|
||||||
for(i=1;i<6;i++)
|
|
||||||
{
|
|
||||||
hBStream[i]=CreateSolidBrush(crStreamCol[i]);
|
|
||||||
hPAdsr[i]=CreatePen(PS_SOLID,0,crAdsrCol[i]);
|
|
||||||
}
|
|
||||||
SetTimer(hW,999,50,NULL); // now create update timer
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------// destroy
|
|
||||||
case WM_DESTROY:
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
KillTimer(hW,999); // first kill timer
|
|
||||||
for(i=0;i<6;i++) // then kill brushes/pens
|
|
||||||
{
|
|
||||||
DeleteObject(hBStream[i]);
|
|
||||||
DeleteObject(hPAdsr[i]);
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
//--------------------------------------------------// timer
|
|
||||||
case WM_TIMER:
|
|
||||||
{
|
|
||||||
if(wParam==999) DisplayDebugInfos(hW); // update all values
|
|
||||||
}break;
|
|
||||||
//--------------------------------------------------// command
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
|
||||||
if(wParam==IDCANCEL) iDebugMode=2; // cancel? raise flag for destroying the dialog
|
|
||||||
|
|
||||||
if(wParam>=IDC_CORE1 && wParam<=IDC_CORE2) // core clicked?
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if(IsDlgButtonChecked(hW,IDC_CORE1)) // -> sel correct half of channels
|
|
||||||
iCoreOffset=0;
|
|
||||||
else iCoreOffset=24;
|
|
||||||
|
|
||||||
for(i=IDC_MUTE1;i<=IDC_MUTE24;i++)
|
|
||||||
{
|
|
||||||
if(s_chan[i-IDC_MUTE1+iCoreOffset].iMute)
|
|
||||||
CheckDlgButton(hW,i,TRUE);
|
|
||||||
else CheckDlgButton(hW,i,FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidateRect(hW,NULL,TRUE);
|
|
||||||
UpdateWindow(hW);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wParam>=IDC_MUTE1 && wParam<=IDC_MUTE24) // mute clicked?
|
|
||||||
{
|
|
||||||
if(IsDlgButtonChecked(hW,wParam)) // -> mute/unmute it
|
|
||||||
s_chan[wParam-IDC_MUTE1+iCoreOffset].iMute=1;
|
|
||||||
else
|
|
||||||
s_chan[wParam-IDC_MUTE1+iCoreOffset].iMute=0;
|
|
||||||
}
|
|
||||||
// all mute/unmute
|
|
||||||
if(wParam==IDC_MUTEOFF) SendMessage(hW,WM_MUTE,0,0);
|
|
||||||
if(wParam==IDC_MUTEON) SendMessage(hW,WM_MUTE,1,0);
|
|
||||||
|
|
||||||
if(wParam>=IDC_CHAN1 && wParam<=IDC_CHAN24) // sel channel
|
|
||||||
{
|
|
||||||
if(IsDlgButtonChecked(hW,wParam))
|
|
||||||
{
|
|
||||||
iSelChannel=wParam-IDC_CHAN1;
|
|
||||||
SetDlgItemInt(hW,IDC_CHANNUM,iSelChannel+1,FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
//--------------------------------------------------// mute
|
|
||||||
case WM_MUTE:
|
|
||||||
{ // will be called by the mute/unmute all button and on savestate load
|
|
||||||
int i;
|
|
||||||
for(i=IDC_MUTE1;i<=IDC_MUTE24;i++)
|
|
||||||
{
|
|
||||||
CheckDlgButton(hW,i,wParam);
|
|
||||||
if(wParam)
|
|
||||||
s_chan[i-IDC_MUTE1+iCoreOffset].iMute=1;
|
|
||||||
else
|
|
||||||
s_chan[i-IDC_MUTE1+iCoreOffset].iMute=0;
|
|
||||||
}
|
|
||||||
}break;
|
|
||||||
//--------------------------------------------------// size
|
|
||||||
case WM_SIZE:
|
|
||||||
if(wParam==SIZE_MINIMIZED) SetFocus(hWMain); // if we get minimized, set the foxus to the main window
|
|
||||||
break;
|
|
||||||
//--------------------------------------------------// setcursor
|
|
||||||
case WM_SETCURSOR:
|
|
||||||
{
|
|
||||||
SetCursor(LoadCursor(NULL,IDC_ARROW)); // force the arrow
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------//
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <stdio.h>
|
|
||||||
extern FILE * LogFile;
|
|
||||||
void logprintf(LPCTSTR pFormat, ...)
|
|
||||||
{
|
|
||||||
if(iDebugMode!=1) return;
|
|
||||||
if(!IsWindow(hWDebug)) return;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
va_list list;
|
|
||||||
|
|
||||||
va_start(list,pFormat);
|
|
||||||
vfprintf(LogFile, pFormat, list);
|
|
||||||
va_end(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
debug.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
BOOL CALLBACK DebugDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
void logprintf(LPCTSTR pFormat, ...);
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define logprintf 0&&
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,414 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
dma.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "externals.h"
|
|
||||||
#include "registers.h"
|
|
||||||
#include "debug.h"
|
|
||||||
extern void (CALLBACK *irqCallbackDMA4)(); // func of main emu, called on spu irq
|
|
||||||
extern void (CALLBACK *irqCallbackDMA7)(); // func of main emu, called on spu irq
|
|
||||||
extern void (CALLBACK *irqCallbackSPU2)(); // func of main emu, called on spu irq
|
|
||||||
unsigned short interrupt;
|
|
||||||
extern unsigned long SPUCycles;
|
|
||||||
unsigned long SPUStartCycle[2];
|
|
||||||
unsigned long SPUTargetCycle[2];
|
|
||||||
|
|
||||||
unsigned long MemAddr[2];
|
|
||||||
|
|
||||||
ADMA Adma4;
|
|
||||||
ADMA Adma7;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// READ DMA (many values)
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2readDMA4Mem(unsigned short * pusPSXMem,int iSize)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1)
|
|
||||||
{
|
|
||||||
logprintf("READDMA4 %X - %X\r\n",spuAddr2[0],iSize);
|
|
||||||
|
|
||||||
if(spuAddr2[0]<=0x1fff)
|
|
||||||
logprintf("# OUTPUT AREA ACCESS #############\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(i=0;i<iSize;i++)
|
|
||||||
{
|
|
||||||
*pusPSXMem++=spuMem[spuAddr2[0]]; // spu addr 0 got by writeregister
|
|
||||||
if(spuCtrl2[0]&0x40 && spuIrq2[0] == spuAddr2[0]){
|
|
||||||
regArea[0x7C0] |= 0x4;
|
|
||||||
regArea[PS2_IRQINFO] |= 0x4;
|
|
||||||
irqCallbackSPU2();
|
|
||||||
}
|
|
||||||
spuAddr2[0]++; // inc spu addr
|
|
||||||
MemAddr[0]+=2;
|
|
||||||
if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
|
|
||||||
}
|
|
||||||
|
|
||||||
spuAddr2[0]+=19; //Transfer Local To Host TSAH/L + Data Size + 20 (already +1'd)
|
|
||||||
|
|
||||||
|
|
||||||
iSpuAsyncWait=0;
|
|
||||||
|
|
||||||
// got from J.F. and Kanodin... is it needed?
|
|
||||||
spuStat2[0]&=~0x80; // DMA complete
|
|
||||||
//if(regArea[(PS2_C0_ADMAS)>>1] != 1) {
|
|
||||||
// if((regArea[(PS2_C0_ATTR)>>1] & 0x30)) {
|
|
||||||
SPUStartCycle[0] = SPUCycles;
|
|
||||||
SPUTargetCycle[0] = iSize;
|
|
||||||
interrupt |= (1<<1);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//regArea[(PS2_C0_ADMAS)>>1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2readDMA7Mem(unsigned short * pusPSXMem,int iSize)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1)
|
|
||||||
{
|
|
||||||
logprintf("READDMA7 %X - %X\r\n",spuAddr2[1],iSize);
|
|
||||||
|
|
||||||
if(spuAddr2[1]<=0x1fff)
|
|
||||||
logprintf("# OUTPUT AREA ACCESS #############\r\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(i=0;i<iSize;i++)
|
|
||||||
{
|
|
||||||
*pusPSXMem++=spuMem[spuAddr2[1]]; // spu addr 1 got by writeregister
|
|
||||||
if(spuCtrl2[1]&0x40 && spuIrq2[1] == spuAddr2[1]){
|
|
||||||
regArea[0x7C0] |= 0x8;
|
|
||||||
regArea[PS2_IRQINFO] |= 0x8;
|
|
||||||
irqCallbackSPU2();
|
|
||||||
}
|
|
||||||
spuAddr2[1]++; // inc spu addr
|
|
||||||
MemAddr[1]+=2;
|
|
||||||
if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
|
|
||||||
}
|
|
||||||
|
|
||||||
spuAddr2[1]+=19; //Transfer Local To Host TSAH/L + Data Size + 20 (already +1'd)
|
|
||||||
|
|
||||||
iSpuAsyncWait=0;
|
|
||||||
|
|
||||||
// got from J.F. and Kanodin... is it needed?
|
|
||||||
spuStat2[1]&=~0x80; // DMA complete
|
|
||||||
// if(regArea[(PS2_C1_ADMAS)>>1] != 2) {
|
|
||||||
// if((regArea[(PS2_C1_ATTR)>>1] & 0x30)) {
|
|
||||||
SPUStartCycle[1] = SPUCycles;
|
|
||||||
SPUTargetCycle[1] = iSize;
|
|
||||||
interrupt |= (1<<2);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//regArea[(PS2_C1_ADMAS)>>1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// WRITE DMA (many values)
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
// AutoDMA's are used to transfer to the DIRECT INPUT area of the spu2 memory
|
|
||||||
// Left and Right channels are always interleaved together in the transfer so
|
|
||||||
// the AutoDMA's deinterleaves them and transfers them. An interrupt is
|
|
||||||
// generated when half of the buffer (256 short-words for left and 256
|
|
||||||
// short-words for right ) has been transferred. Another interrupt occurs at
|
|
||||||
// the end of the transfer.
|
|
||||||
|
|
||||||
int ADMAS4Write()
|
|
||||||
{
|
|
||||||
if(interrupt & 0x2) return 0;
|
|
||||||
if(Adma4.AmountLeft <= 0) {
|
|
||||||
if(Adma4.TempAmount == 0) return 1;
|
|
||||||
Adma4.AmountLeft = Adma4.TempAmount;
|
|
||||||
Adma4.MemAddr = Adma4.TempMem;
|
|
||||||
Adma4.TempMem = NULL;
|
|
||||||
Adma4.TempAmount = 0;
|
|
||||||
}
|
|
||||||
Adma4.TransferAmount = min(512, Adma4.AmountLeft);
|
|
||||||
if(Adma4.ADMAPos == 512) Adma4.ADMAPos = 0;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1)
|
|
||||||
{
|
|
||||||
logprintf("ADMAWRITE4 %X - %X\r\n",spuAddr2[0],Adma4.AmountLeft);
|
|
||||||
if(Adma4.AmountLeft<512) logprintf("FUCK YOU %X\r\n",Adma4.AmountLeft);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SPU2 Deinterleaves the Left and Right Channels
|
|
||||||
memcpy((short*)(spuMem + Adma4.ADMAPos + 0x2000),(short*)Adma4.MemAddr,Adma4.TransferAmount);
|
|
||||||
Adma4.MemAddr += Adma4.TransferAmount / 2;
|
|
||||||
memcpy((short*)(spuMem + Adma4.ADMAPos + 0x2200),(short*)Adma4.MemAddr,Adma4.TransferAmount);
|
|
||||||
Adma4.MemAddr += Adma4.TransferAmount / 2;
|
|
||||||
|
|
||||||
Adma4.ADMAPos += Adma4.TransferAmount / 2;
|
|
||||||
MemAddr[0] += Adma4.TransferAmount * 2;
|
|
||||||
//MemAddr[0] += 1024;
|
|
||||||
Adma4.AmountLeft-= Adma4.TransferAmount;
|
|
||||||
spuStat2[0]&=~0x80;
|
|
||||||
|
|
||||||
if(Adma4.AmountLeft == 0)
|
|
||||||
{
|
|
||||||
if(Adma4.IRQ == 0){
|
|
||||||
Adma4.IRQ = 1;
|
|
||||||
irqCallbackDMA4();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ADMAS7Write()
|
|
||||||
{
|
|
||||||
if(interrupt & 0x4) return 0;
|
|
||||||
if(Adma7.AmountLeft <= 0) {
|
|
||||||
if(Adma7.TempAmount == 0) return 1;
|
|
||||||
Adma7.AmountLeft = Adma7.TempAmount;
|
|
||||||
Adma7.MemAddr = Adma7.TempMem;
|
|
||||||
Adma7.TempMem = NULL;
|
|
||||||
Adma7.TempAmount = 0;
|
|
||||||
}
|
|
||||||
Adma7.TransferAmount = min(512, Adma7.AmountLeft);
|
|
||||||
if(Adma7.ADMAPos == 512) Adma7.ADMAPos = 0;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1)
|
|
||||||
{
|
|
||||||
logprintf("ADMAWRITE7 %X - %X\r\n",spuAddr2[1],Adma7.AmountLeft);
|
|
||||||
if(Adma7.AmountLeft<512) logprintf("FUCK YOU %X\r\n",Adma7.AmountLeft);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SPU2 Deinterleaves the Left and Right Channels
|
|
||||||
memcpy((short*)(spuMem + Adma7.ADMAPos + 0x2400),(short*)Adma7.MemAddr,Adma7.TransferAmount);
|
|
||||||
Adma7.MemAddr += Adma7.TransferAmount / 2;
|
|
||||||
memcpy((short*)(spuMem + Adma7.ADMAPos + 0x2600),(short*)Adma7.MemAddr,Adma7.TransferAmount);
|
|
||||||
Adma7.MemAddr += Adma7.TransferAmount / 2;
|
|
||||||
|
|
||||||
Adma7.ADMAPos += Adma7.TransferAmount / 2;
|
|
||||||
MemAddr[1] += Adma7.TransferAmount * 2;
|
|
||||||
//MemAddr[1] += 1024;
|
|
||||||
Adma7.AmountLeft-=Adma7.TransferAmount;
|
|
||||||
spuStat2[1]&=~0x80;
|
|
||||||
|
|
||||||
if(Adma7.AmountLeft == 0)
|
|
||||||
{
|
|
||||||
if(Adma7.IRQ == 0){
|
|
||||||
Adma7.IRQ = 1;
|
|
||||||
irqCallbackDMA7();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
extern FILE * LogFile;
|
|
||||||
EXPORT_GCC void CALLBACK SPU2writeDMA4Mem(short * pMem,unsigned int iSize)
|
|
||||||
{
|
|
||||||
//if(Adma4.AmountLeft > 0) return;
|
|
||||||
if(regArea[PS2_C0_ADMAS] & 0x1 && (spuCtrl2[0] & 0x30) == 0 && iSize)
|
|
||||||
{
|
|
||||||
//fwrite(pMem,iSize<<1,1,LogFile);
|
|
||||||
// memset(&Adma4,0,sizeof(ADMA));
|
|
||||||
//if( !Adma4.Enabled )
|
|
||||||
// Adma4.Index = 0;
|
|
||||||
//Adma4.ADMAPos = 0;
|
|
||||||
if((Adma4.ADMAPos == 512 && Adma4.Index <= 256) || (Adma4.ADMAPos == 256 && Adma4.Index >= 256) || Adma4.AmountLeft >= 512) {
|
|
||||||
Adma4.TempMem = pMem;
|
|
||||||
Adma4.TempAmount = iSize;
|
|
||||||
} else {
|
|
||||||
Adma4.MemAddr = pMem;
|
|
||||||
Adma4.AmountLeft += iSize;
|
|
||||||
ADMAS4Write();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1)
|
|
||||||
{
|
|
||||||
logprintf("WRITEDMA4 %X - %X\r\n",spuAddr2[0],iSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy((unsigned char*)(spuMem+spuAddr2[0]),(unsigned char*)pMem,iSize<<1);
|
|
||||||
if(spuCtrl2[0]&0x40 && (spuIrq2[0] >= spuAddr2[0] && spuIrq2[0] <= (spuAddr2[0] + iSize))){
|
|
||||||
regArea[0x7C0] |= 0x4;
|
|
||||||
regArea[PS2_IRQINFO] |= 0x4;
|
|
||||||
irqCallbackSPU2();
|
|
||||||
}
|
|
||||||
spuAddr2[0] += iSize;
|
|
||||||
|
|
||||||
if(spuAddr2[0]>0x23FF) spuAddr2[0] = 0x2000;
|
|
||||||
|
|
||||||
MemAddr[0] += iSize<<1;
|
|
||||||
spuStat2[0]&=~0x80;
|
|
||||||
SPUStartCycle[0] = SPUCycles;
|
|
||||||
SPUTargetCycle[0] = 1;//iSize;
|
|
||||||
interrupt |= (1<<1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogRawSound(void* pleft, int leftstride, void* pright, int rightstride, int numsamples)
|
|
||||||
{
|
|
||||||
#ifdef _DEBUG
|
|
||||||
static FILE* g_fLogSound = NULL;
|
|
||||||
|
|
||||||
char* left = (char*)pleft;
|
|
||||||
char* right = (char*)pright;
|
|
||||||
unsigned short* tempbuf;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if( g_fLogSound == NULL ) {
|
|
||||||
g_fLogSound = fopen("rawsndbuf.pcm", "wb");
|
|
||||||
if( g_fLogSound == NULL )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempbuf = (unsigned short*)malloc(4*numsamples);
|
|
||||||
|
|
||||||
for(i = 0; i < numsamples; ++i) {
|
|
||||||
tempbuf[2*i+0] = *(unsigned short*)left;
|
|
||||||
tempbuf[2*i+1] = *(unsigned short*)right;
|
|
||||||
left += leftstride;
|
|
||||||
right += rightstride;
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(&tempbuf[0], 4*numsamples, 1, g_fLogSound);
|
|
||||||
free(tempbuf);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(unsigned short * pMem,int iSize)
|
|
||||||
{
|
|
||||||
// For AutoDMA, the ATTR register's bit 5 and 6 are cleared.
|
|
||||||
// bit 5 means Data Input Thru Register
|
|
||||||
// bit 6 means Data Input Thru DMA
|
|
||||||
//if(Adma7.AmountLeft > 0) return;
|
|
||||||
|
|
||||||
if((regArea[PS2_C1_ADMAS] & 0x2) && (spuCtrl2[1] & 0x30) == 0 && iSize)
|
|
||||||
{
|
|
||||||
//fwrite(pMem,iSize<<1,1,LogFile);
|
|
||||||
// memset(&Adma7,0,sizeof(ADMA));
|
|
||||||
//if( !Adma7.Enabled )
|
|
||||||
// Adma7.Index = 0;
|
|
||||||
//Adma7.ADMAPos = 0;
|
|
||||||
if((Adma7.ADMAPos == 512 && Adma7.Index <= 256) || (Adma7.ADMAPos == 256 && Adma7.Index >= 256) || Adma7.AmountLeft >= 512) {
|
|
||||||
Adma7.TempMem = pMem;
|
|
||||||
Adma7.TempAmount = iSize;
|
|
||||||
} else {
|
|
||||||
Adma7.MemAddr = pMem;
|
|
||||||
Adma7.AmountLeft += iSize;
|
|
||||||
ADMAS7Write();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1)
|
|
||||||
{
|
|
||||||
logprintf("WRITEDMA7 %X - %X\r\n",spuAddr2[1],iSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy((short*)(spuMem+spuAddr2[1]),(short*)pMem,iSize<<1);
|
|
||||||
if(spuCtrl2[1]&0x40 && (spuIrq2[1] >= spuAddr2[1] && spuIrq2[1] <= (spuAddr2[1] + iSize))){
|
|
||||||
regArea[0x7C0] |= 0x8;
|
|
||||||
regArea[PS2_IRQINFO] |= 8;
|
|
||||||
irqCallbackSPU2();
|
|
||||||
}
|
|
||||||
spuAddr2[1] += iSize;
|
|
||||||
|
|
||||||
if(spuAddr2[1]>0x27FF) spuAddr2[1] = 0x2400;
|
|
||||||
|
|
||||||
MemAddr[1] += iSize<<1;
|
|
||||||
spuStat2[1]&=~0x80;
|
|
||||||
SPUStartCycle[1] = SPUCycles;
|
|
||||||
SPUTargetCycle[1] = 1;//iSize;
|
|
||||||
interrupt |= (1<<2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// INTERRUPTS
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void InterruptDMA4(void)
|
|
||||||
{
|
|
||||||
// taken from linuzappz NULL spu2
|
|
||||||
// spu2Rs16(CORE0_ATTR)&= ~0x30;
|
|
||||||
// spu2Rs16(REG__1B0) = 0;
|
|
||||||
// spu2Rs16(SPU2_STATX_WRDY_M)|= 0x80;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1) logprintf("IRQDMA4\r\n");
|
|
||||||
#endif
|
|
||||||
Adma4.IRQ = 0;
|
|
||||||
spuCtrl2[0]&=~0x30;
|
|
||||||
spuStat2[0]|=0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2interruptDMA4(void)
|
|
||||||
{
|
|
||||||
InterruptDMA4();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptDMA7(void)
|
|
||||||
{
|
|
||||||
// taken from linuzappz NULL spu2
|
|
||||||
// spu2Rs16(CORE1_ATTR)&= ~0x30;
|
|
||||||
// spu2Rs16(REG__5B0) = 0;
|
|
||||||
// spu2Rs16(SPU2_STATX_DREQ)|= 0x80;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1) logprintf("IRQDMA7\r\n");
|
|
||||||
#endif
|
|
||||||
Adma7.IRQ = 0;
|
|
||||||
spuStat2[1]|=0x80;
|
|
||||||
spuCtrl2[1]&=~0x30;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2interruptDMA7(void)
|
|
||||||
{
|
|
||||||
InterruptDMA7();
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2WriteMemAddr(int core, unsigned long value)
|
|
||||||
{
|
|
||||||
MemAddr[core] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_GCC unsigned long CALLBACK SPU2ReadMemAddr(int core)
|
|
||||||
{
|
|
||||||
return MemAddr[core];
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
dma.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
void InterruptDMA4(void);
|
|
||||||
void InterruptDMA7(void);
|
|
|
@ -1,268 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
dsound.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2005/08/29 - Pete
|
|
||||||
// - changed to 48Khz output
|
|
||||||
//
|
|
||||||
// 2003/01/12 - Pete
|
|
||||||
// - added recording funcs
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_DSOUND
|
|
||||||
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#define _LPCWAVEFORMATEX_DEFINED
|
|
||||||
#include "dsound.h"
|
|
||||||
|
|
||||||
#include "record.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// dsound globals
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
LPDIRECTSOUND lpDS;
|
|
||||||
LPDIRECTSOUNDBUFFER lpDSBPRIMARY = NULL;
|
|
||||||
LPDIRECTSOUNDBUFFER lpDSBSECONDARY1 = NULL;
|
|
||||||
LPDIRECTSOUNDBUFFER lpDSBSECONDARY2 = NULL;
|
|
||||||
DSBUFFERDESC dsbd;
|
|
||||||
DSBUFFERDESC dsbdesc;
|
|
||||||
DSCAPS dscaps;
|
|
||||||
DSBCAPS dsbcaps;
|
|
||||||
|
|
||||||
unsigned long LastWrite=0xffffffff;
|
|
||||||
unsigned long LastWriteS=0xffffffff;
|
|
||||||
unsigned long LastPlay=0;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// SETUP SOUND
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SetupSound(void)
|
|
||||||
{
|
|
||||||
HRESULT dsval;WAVEFORMATEX pcmwf;
|
|
||||||
|
|
||||||
dsval = DirectSoundCreate(NULL,&lpDS,NULL);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
MessageBox(hWMain,"DirectSoundCreate!","Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DS_OK!=IDirectSound_SetCooperativeLevel(lpDS,hWMain, DSSCL_PRIORITY))
|
|
||||||
{
|
|
||||||
if(DS_OK!=IDirectSound_SetCooperativeLevel(lpDS,hWMain, DSSCL_NORMAL))
|
|
||||||
{
|
|
||||||
MessageBox(hWMain,"SetCooperativeLevel!","Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&dsbd,0,sizeof(DSBUFFERDESC));
|
|
||||||
dsbd.dwSize = sizeof(DSBUFFERDESC); // NT4 hack! sizeof(dsbd);
|
|
||||||
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
|
||||||
dsbd.dwBufferBytes = 0;
|
|
||||||
dsbd.lpwfxFormat = NULL;
|
|
||||||
|
|
||||||
dsval=IDirectSound_CreateSoundBuffer(lpDS,&dsbd,&lpDSBPRIMARY,NULL);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
MessageBox(hWMain, "CreateSoundBuffer (Primary)", "Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&pcmwf, 0, sizeof(WAVEFORMATEX));
|
|
||||||
pcmwf.wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
|
|
||||||
pcmwf.nChannels = 2;
|
|
||||||
pcmwf.nBlockAlign = 4;
|
|
||||||
|
|
||||||
pcmwf.nSamplesPerSec = 48000;
|
|
||||||
|
|
||||||
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
|
|
||||||
pcmwf.wBitsPerSample = 16;
|
|
||||||
|
|
||||||
dsval=IDirectSoundBuffer_SetFormat(lpDSBPRIMARY,&pcmwf);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
MessageBox(hWMain, "SetFormat!", "Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dscaps.dwSize = sizeof(DSCAPS);
|
|
||||||
dsbcaps.dwSize = sizeof(DSBCAPS);
|
|
||||||
IDirectSound_GetCaps(lpDS,&dscaps);
|
|
||||||
IDirectSoundBuffer_GetCaps(lpDSBPRIMARY,&dsbcaps);
|
|
||||||
|
|
||||||
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
|
|
||||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC); // NT4 hack! sizeof(DSBUFFERDESC);
|
|
||||||
dsbdesc.dwFlags = DSBCAPS_LOCHARDWARE | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
|
|
||||||
dsbdesc.dwBufferBytes = SOUNDSIZE;
|
|
||||||
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
|
|
||||||
|
|
||||||
dsval=IDirectSound_CreateSoundBuffer(lpDS,&dsbdesc,&lpDSBSECONDARY1,NULL);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
|
|
||||||
dsval=IDirectSound_CreateSoundBuffer(lpDS,&dsbdesc,&lpDSBSECONDARY1,NULL);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
MessageBox(hWMain,"CreateSoundBuffer (Secondary1)", "Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dsval=IDirectSoundBuffer_Play(lpDSBPRIMARY,0,0,DSBPLAY_LOOPING);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
MessageBox(hWMain,"Play (Primary)","Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dsval=IDirectSoundBuffer_Play(lpDSBSECONDARY1,0,0,DSBPLAY_LOOPING);
|
|
||||||
if(dsval!=DS_OK)
|
|
||||||
{
|
|
||||||
MessageBox(hWMain,"Play (Secondary1)","Error",MB_OK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// REMOVE SOUND
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void RemoveSound(void)
|
|
||||||
{
|
|
||||||
int iRes;
|
|
||||||
|
|
||||||
if(iDoRecord) RecordStop();
|
|
||||||
|
|
||||||
if(lpDSBSECONDARY1!=NULL)
|
|
||||||
{
|
|
||||||
IDirectSoundBuffer_Stop(lpDSBSECONDARY1);
|
|
||||||
iRes=IDirectSoundBuffer_Release(lpDSBSECONDARY1);
|
|
||||||
// FF says such a loop is bad... Demo says it's good... Pete doesn't care
|
|
||||||
while(iRes!=0) iRes=IDirectSoundBuffer_Release(lpDSBSECONDARY1);
|
|
||||||
lpDSBSECONDARY1=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lpDSBPRIMARY!=NULL)
|
|
||||||
{
|
|
||||||
IDirectSoundBuffer_Stop(lpDSBPRIMARY);
|
|
||||||
iRes=IDirectSoundBuffer_Release(lpDSBPRIMARY);
|
|
||||||
// FF says such a loop is bad... Demo says it's good... Pete doesn't care
|
|
||||||
while(iRes!=0) iRes=IDirectSoundBuffer_Release(lpDSBPRIMARY);
|
|
||||||
lpDSBPRIMARY=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lpDS!=NULL)
|
|
||||||
{
|
|
||||||
iRes=IDirectSound_Release(lpDS);
|
|
||||||
// FF says such a loop is bad... Demo says it's good... Pete doesn't care
|
|
||||||
while(iRes!=0) iRes=IDirectSound_Release(lpDS);
|
|
||||||
lpDS=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// GET BYTES BUFFERED
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
unsigned long SoundGetBytesBuffered(void)
|
|
||||||
{
|
|
||||||
unsigned long cplay,cwrite;
|
|
||||||
|
|
||||||
if(LastWrite==0xffffffff) return 0;
|
|
||||||
|
|
||||||
IDirectSoundBuffer_GetCurrentPosition(lpDSBSECONDARY1,&cplay,&cwrite);
|
|
||||||
|
|
||||||
if(cplay>SOUNDSIZE) return SOUNDSIZE;
|
|
||||||
|
|
||||||
if(cplay<LastWrite) return LastWrite-cplay;
|
|
||||||
return (SOUNDSIZE-cplay)+LastWrite;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// FEED SOUND DATA
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SoundFeedVoiceData(unsigned char* pSound,long lBytes)
|
|
||||||
{
|
|
||||||
LPVOID lpvPtr1, lpvPtr2;
|
|
||||||
unsigned long dwBytes1,dwBytes2;
|
|
||||||
unsigned long *lpSS, *lpSD;
|
|
||||||
unsigned long dw,cplay,cwrite;
|
|
||||||
HRESULT hr;
|
|
||||||
unsigned long status;
|
|
||||||
|
|
||||||
if(iDoRecord) RecordBuffer(pSound,lBytes);
|
|
||||||
|
|
||||||
IDirectSoundBuffer_GetStatus(lpDSBSECONDARY1,&status);
|
|
||||||
if(status&DSBSTATUS_BUFFERLOST)
|
|
||||||
{
|
|
||||||
if(IDirectSoundBuffer_Restore(lpDSBSECONDARY1)!=DS_OK) return;
|
|
||||||
IDirectSoundBuffer_Play(lpDSBSECONDARY1,0,0,DSBPLAY_LOOPING);
|
|
||||||
}
|
|
||||||
|
|
||||||
IDirectSoundBuffer_GetCurrentPosition(lpDSBSECONDARY1,&cplay,&cwrite);
|
|
||||||
|
|
||||||
if(LastWrite==0xffffffff) LastWrite=cwrite;
|
|
||||||
|
|
||||||
hr=IDirectSoundBuffer_Lock(lpDSBSECONDARY1,LastWrite,lBytes,
|
|
||||||
&lpvPtr1, &dwBytes1,
|
|
||||||
&lpvPtr2, &dwBytes2,
|
|
||||||
0);
|
|
||||||
|
|
||||||
if(hr!=DS_OK) {LastWrite=0xffffffff;return;}
|
|
||||||
|
|
||||||
lpSD=(unsigned long *)lpvPtr1;
|
|
||||||
dw=dwBytes1>>2;
|
|
||||||
|
|
||||||
lpSS=(unsigned long *)pSound;
|
|
||||||
while(dw) {*lpSD++=*lpSS++;dw--;}
|
|
||||||
|
|
||||||
if(lpvPtr2)
|
|
||||||
{
|
|
||||||
lpSD=(unsigned long *)lpvPtr2;
|
|
||||||
dw=dwBytes2>>2;
|
|
||||||
while(dw) {*lpSD++=*lpSS++;dw--;}
|
|
||||||
}
|
|
||||||
|
|
||||||
IDirectSoundBuffer_Unlock(lpDSBSECONDARY1,lpvPtr1,dwBytes1,lpvPtr2,dwBytes2);
|
|
||||||
LastWrite+=lBytes;
|
|
||||||
if(LastWrite>=SOUNDSIZE) LastWrite-=SOUNDSIZE;
|
|
||||||
LastPlay=cplay;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,36 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
dsoundoss.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
|
|
||||||
void SetupSound(void);
|
|
||||||
void RemoveSound(void);
|
|
||||||
unsigned long SoundGetBytesBuffered(void);
|
|
||||||
void SoundFeedStreamData(unsigned char* pSound,long lBytes);
|
|
||||||
|
|
||||||
#ifndef _WINDOWS
|
|
||||||
unsigned long timeGetTime();
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,364 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
externals.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2002/04/04 - Pete
|
|
||||||
// - increased channel struct for interpolation
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
// generic defines
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//#define PSE_LT_SPU 4
|
|
||||||
//#define PSE_SPU_ERR_SUCCESS 0
|
|
||||||
//#define PSE_SPU_ERR -60
|
|
||||||
//#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1
|
|
||||||
//#define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2
|
|
||||||
|
|
||||||
#ifndef max
|
|
||||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
|
||||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// spu defines
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// sound buffer sizes
|
|
||||||
// 500 ms complete sound buffer
|
|
||||||
#define SOUNDSIZE 76800
|
|
||||||
|
|
||||||
// 200 ms test buffer... if less than that is buffered, a new upload will happen
|
|
||||||
#define TESTSIZE 26304//13152
|
|
||||||
|
|
||||||
// num of channels
|
|
||||||
#define MAXCHAN 48
|
|
||||||
#define HLFCHAN 24
|
|
||||||
|
|
||||||
// ~ 1 ms of data
|
|
||||||
#define NSSIZE 48
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// struct defines
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// ADMA Channels
|
|
||||||
extern EXPORT_GCC void CALLBACK SPU2async(unsigned long cycle);
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned short * MemAddr;
|
|
||||||
unsigned short * TempMem;
|
|
||||||
unsigned int Index;
|
|
||||||
unsigned int AmountLeft;
|
|
||||||
unsigned int ADMAPos;
|
|
||||||
unsigned int TransferAmount;
|
|
||||||
int IRQ;
|
|
||||||
int TempAmount;
|
|
||||||
} ADMA;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int Left;
|
|
||||||
int Right;
|
|
||||||
} DINPUT;
|
|
||||||
|
|
||||||
// ADSR INFOS PER CHANNEL
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int AttackModeExp;
|
|
||||||
long AttackTime;
|
|
||||||
long DecayTime;
|
|
||||||
long SustainLevel;
|
|
||||||
int SustainModeExp;
|
|
||||||
long SustainModeDec;
|
|
||||||
long SustainTime;
|
|
||||||
int ReleaseModeExp;
|
|
||||||
unsigned long ReleaseVal;
|
|
||||||
long ReleaseTime;
|
|
||||||
long ReleaseStartTime;
|
|
||||||
long ReleaseVol;
|
|
||||||
long lTime;
|
|
||||||
long lVolume;
|
|
||||||
} ADSRInfo;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int State;
|
|
||||||
int AttackModeExp;
|
|
||||||
int AttackRate;
|
|
||||||
int DecayRate;
|
|
||||||
int SustainLevel;
|
|
||||||
int SustainModeExp;
|
|
||||||
int SustainIncrease;
|
|
||||||
int SustainRate;
|
|
||||||
int ReleaseModeExp;
|
|
||||||
int ReleaseRate;
|
|
||||||
int EnvelopeVol;
|
|
||||||
long lVolume;
|
|
||||||
long lDummy1;
|
|
||||||
long lDummy2;
|
|
||||||
} ADSRInfoEx;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Tmp Flags
|
|
||||||
|
|
||||||
// used for debug channel muting
|
|
||||||
#define FLAG_MUTE 1
|
|
||||||
|
|
||||||
// used for simple interpolation
|
|
||||||
#define FLAG_IPOL0 2
|
|
||||||
#define FLAG_IPOL1 4
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// MAIN CHANNEL STRUCT
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
// no mutexes used anymore... don't need them to sync access
|
|
||||||
//HANDLE hMutex;
|
|
||||||
|
|
||||||
int bNew; // start flag
|
|
||||||
|
|
||||||
int iSBPos; // mixing stuff
|
|
||||||
int spos;
|
|
||||||
int sinc;
|
|
||||||
int SB[32+32]; // Pete added another 32 dwords in 1.6 ... prevents overflow issues with gaussian/cubic interpolation (thanx xodnizel!), and can be used for even better interpolations, eh? :)
|
|
||||||
int sval;
|
|
||||||
|
|
||||||
unsigned char * pStart; // start ptr into sound mem
|
|
||||||
unsigned char * pCurr; // current pos in sound mem
|
|
||||||
unsigned char * pLoop; // loop ptr in sound mem
|
|
||||||
|
|
||||||
int iStartAdr;
|
|
||||||
int iLoopAdr;
|
|
||||||
int iNextAdr;
|
|
||||||
|
|
||||||
int bOn; // is channel active (sample playing?)
|
|
||||||
int bStop; // is channel stopped (sample _can_ still be playing, ADSR Release phase)
|
|
||||||
int bEndPoint; // end point reached
|
|
||||||
int bReverbL; // can we do reverb on this channel? must have ctrl register bit, to get active
|
|
||||||
int bReverbR;
|
|
||||||
|
|
||||||
int bVolumeL; // Volume on/off
|
|
||||||
int bVolumeR;
|
|
||||||
|
|
||||||
int iActFreq; // current psx pitch
|
|
||||||
int iUsedFreq; // current pc pitch
|
|
||||||
int iLeftVolume; // left volume
|
|
||||||
int iLeftVolRaw; // left psx volume value
|
|
||||||
int bIgnoreLoop; // ignore loop bit, if an external loop address is used
|
|
||||||
int iMute; // mute mode
|
|
||||||
int iRightVolume; // right volume
|
|
||||||
int iRightVolRaw; // right psx volume value
|
|
||||||
int iRawPitch; // raw pitch (0...3fff)
|
|
||||||
int iIrqDone; // debug irq done flag
|
|
||||||
int s_1; // last decoding infos
|
|
||||||
int s_2;
|
|
||||||
int bRVBActive; // reverb active flag
|
|
||||||
int bNoise; // noise active flag
|
|
||||||
int bFMod; // freq mod (0=off, 1=sound channel, 2=freq channel)
|
|
||||||
int iOldNoise; // old noise val for this channel
|
|
||||||
ADSRInfo ADSR; // active ADSR settings
|
|
||||||
ADSRInfoEx ADSRX; // next ADSR settings (will be moved to active on sample start)
|
|
||||||
|
|
||||||
} SPUCHAN;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int StartAddr; // reverb area start addr in samples
|
|
||||||
int EndAddr; // reverb area end addr in samples
|
|
||||||
int CurrAddr; // reverb area curr addr in samples
|
|
||||||
|
|
||||||
int VolLeft;
|
|
||||||
int VolRight;
|
|
||||||
int iLastRVBLeft;
|
|
||||||
int iLastRVBRight;
|
|
||||||
int iRVBLeft;
|
|
||||||
int iRVBRight;
|
|
||||||
int iCnt;
|
|
||||||
|
|
||||||
int FB_SRC_A; // (offset)
|
|
||||||
int FB_SRC_B; // (offset)
|
|
||||||
int IIR_ALPHA; // (coef.)
|
|
||||||
int ACC_COEF_A; // (coef.)
|
|
||||||
int ACC_COEF_B; // (coef.)
|
|
||||||
int ACC_COEF_C; // (coef.)
|
|
||||||
int ACC_COEF_D; // (coef.)
|
|
||||||
int IIR_COEF; // (coef.)
|
|
||||||
int FB_ALPHA; // (coef.)
|
|
||||||
int FB_X; // (coef.)
|
|
||||||
int IIR_DEST_A0; // (offset)
|
|
||||||
int IIR_DEST_A1; // (offset)
|
|
||||||
int ACC_SRC_A0; // (offset)
|
|
||||||
int ACC_SRC_A1; // (offset)
|
|
||||||
int ACC_SRC_B0; // (offset)
|
|
||||||
int ACC_SRC_B1; // (offset)
|
|
||||||
int IIR_SRC_A0; // (offset)
|
|
||||||
int IIR_SRC_A1; // (offset)
|
|
||||||
int IIR_DEST_B0; // (offset)
|
|
||||||
int IIR_DEST_B1; // (offset)
|
|
||||||
int ACC_SRC_C0; // (offset)
|
|
||||||
int ACC_SRC_C1; // (offset)
|
|
||||||
int ACC_SRC_D0; // (offset)
|
|
||||||
int ACC_SRC_D1; // (offset)
|
|
||||||
int IIR_SRC_B1; // (offset)
|
|
||||||
int IIR_SRC_B0; // (offset)
|
|
||||||
int MIX_DEST_A0; // (offset)
|
|
||||||
int MIX_DEST_A1; // (offset)
|
|
||||||
int MIX_DEST_B0; // (offset)
|
|
||||||
int MIX_DEST_B1; // (offset)
|
|
||||||
int IN_COEF_L; // (coef.)
|
|
||||||
int IN_COEF_R; // (coef.)
|
|
||||||
} REVERBInfo;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
extern HINSTANCE hInst;
|
|
||||||
#define WM_MUTE (WM_USER+543)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// SPU.C globals
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_SPU
|
|
||||||
|
|
||||||
// psx buffers / addresses
|
|
||||||
|
|
||||||
extern unsigned short regArea[];
|
|
||||||
extern unsigned short spuMem[];
|
|
||||||
extern unsigned char * spuMemC;
|
|
||||||
extern unsigned char * pSpuIrq[];
|
|
||||||
extern unsigned char * pSpuBuffer;
|
|
||||||
|
|
||||||
// user settings
|
|
||||||
|
|
||||||
extern int iUseXA;
|
|
||||||
extern int iVolume;
|
|
||||||
extern int iXAPitch;
|
|
||||||
extern int iUseTimer;
|
|
||||||
extern int iDebugMode;
|
|
||||||
extern int iRecordMode;
|
|
||||||
extern int iUseReverb;
|
|
||||||
extern int iUseInterpolation;
|
|
||||||
extern int iDisStereo;
|
|
||||||
extern int aSync;
|
|
||||||
// MISC
|
|
||||||
|
|
||||||
extern SPUCHAN s_chan[];
|
|
||||||
extern REVERBInfo rvb[];
|
|
||||||
|
|
||||||
extern unsigned long dwNoiseVal;
|
|
||||||
extern unsigned short spuCtrl2[];
|
|
||||||
extern unsigned short spuStat2[];
|
|
||||||
extern unsigned long spuIrq2[];
|
|
||||||
extern unsigned long spuAddr2[];
|
|
||||||
extern unsigned long spuRvbAddr2[];
|
|
||||||
extern unsigned long spuRvbAEnd2[];
|
|
||||||
|
|
||||||
extern int bEndThread;
|
|
||||||
extern int bThreadEnded;
|
|
||||||
extern int bSpuInit;
|
|
||||||
|
|
||||||
extern int SSumR[];
|
|
||||||
extern int SSumL[];
|
|
||||||
extern int iCycle;
|
|
||||||
extern short * pS;
|
|
||||||
extern unsigned long dwNewChannel2[];
|
|
||||||
extern unsigned long dwEndChannel2[];
|
|
||||||
|
|
||||||
extern int iSpuAsyncWait;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
extern HWND hWMain; // window handle
|
|
||||||
extern HWND hWDebug;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void (CALLBACK *cddavCallback)(unsigned short,unsigned short);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// DSOUND.C globals
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_DSOUND
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
extern unsigned long LastWrite;
|
|
||||||
extern unsigned long LastPlay;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// RECORD.C globals
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_RECORD
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
extern int iDoRecord;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// XA.C globals
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_XA
|
|
||||||
|
|
||||||
extern xa_decode_t * xapGlobal;
|
|
||||||
|
|
||||||
extern unsigned long * XAFeed;
|
|
||||||
extern unsigned long * XAPlay;
|
|
||||||
extern unsigned long * XAStart;
|
|
||||||
extern unsigned long * XAEnd;
|
|
||||||
|
|
||||||
extern unsigned long XARepeat;
|
|
||||||
extern unsigned long XALastVal;
|
|
||||||
|
|
||||||
extern int iLeftXAVol;
|
|
||||||
extern int iRightXAVol;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// REVERB.C globals
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _IN_REVERB
|
|
||||||
|
|
||||||
extern int * sRVBPlay[];
|
|
||||||
extern int * sRVBEnd[];
|
|
||||||
extern int * sRVBStart[];
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,246 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
freeze.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/12/24 - Pete
|
|
||||||
// - freeze functions adapted to pcsx2-0.7
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2003/03/20 - Pete
|
|
||||||
// - fix to prevent the new interpolations from crashing when loading a save state
|
|
||||||
//
|
|
||||||
// 2003/01/06 - Pete
|
|
||||||
// - small changes for version 1.3 adsr save state loading
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_FREEZE
|
|
||||||
|
|
||||||
#include "externals.h"
|
|
||||||
#include "registers.h"
|
|
||||||
#include "spu.h"
|
|
||||||
#include "regs.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// freeze structs
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int size;
|
|
||||||
char *data;
|
|
||||||
} SPUFreeze_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char szSPUName[8];
|
|
||||||
unsigned long ulFreezeVersion;
|
|
||||||
unsigned long ulFreezeSize;
|
|
||||||
unsigned char cSPUPort[64*1024];
|
|
||||||
unsigned char cSPURam[2*1024*1024];
|
|
||||||
} SPUFreeze_Ex_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned long spuIrq0;
|
|
||||||
unsigned long spuIrq1;
|
|
||||||
unsigned long pSpuIrq0;
|
|
||||||
unsigned long pSpuIrq1;
|
|
||||||
unsigned long dummy0;
|
|
||||||
unsigned long dummy1;
|
|
||||||
unsigned long dummy2;
|
|
||||||
unsigned long dummy3;
|
|
||||||
|
|
||||||
SPUCHAN s_chan[MAXCHAN];
|
|
||||||
|
|
||||||
} SPUOSSFreeze_t;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void LoadStateV1(SPUFreeze_Ex_t * pF); // newest version
|
|
||||||
void LoadStateUnknown(SPUFreeze_Ex_t * pF); // unknown format
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// SPUFREEZE: called by main emu on savestate load/save
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
EXPORT_GCC long CALLBACK SPU2freeze(unsigned long ulFreezeMode,SPUFreeze_t * pFt)
|
|
||||||
{
|
|
||||||
int i;SPUOSSFreeze_t * pFO;SPUFreeze_Ex_t * pF;
|
|
||||||
|
|
||||||
if(!pFt) return 0; // first check
|
|
||||||
|
|
||||||
if(ulFreezeMode) // save?
|
|
||||||
{//--------------------------------------------------//
|
|
||||||
pFt->size=sizeof(SPUFreeze_Ex_t)+sizeof(SPUOSSFreeze_t);
|
|
||||||
|
|
||||||
if(ulFreezeMode==2) return 0; // emu just asking for size? bye
|
|
||||||
|
|
||||||
if(!pFt->data) return 0;
|
|
||||||
|
|
||||||
pF=(SPUFreeze_Ex_t *)pFt->data;
|
|
||||||
|
|
||||||
memset(pF,0,pFt->size);
|
|
||||||
|
|
||||||
strcpy(pF->szSPUName,"PBOSS2");
|
|
||||||
pF->ulFreezeVersion=1;
|
|
||||||
pF->ulFreezeSize=pFt->size;
|
|
||||||
// save mode:
|
|
||||||
RemoveTimer(); // stop timer
|
|
||||||
|
|
||||||
memcpy(pF->cSPURam,spuMem,2*1024*1024); // copy common infos
|
|
||||||
memcpy(pF->cSPUPort,regArea,64*1024);
|
|
||||||
|
|
||||||
pFO=(SPUOSSFreeze_t *)(pF+1); // store special stuff
|
|
||||||
|
|
||||||
pFO->spuIrq0=spuIrq2[0];
|
|
||||||
if(pSpuIrq[0]) pFO->pSpuIrq0 = (unsigned long)pSpuIrq[0]-(unsigned long)spuMemC;
|
|
||||||
pFO->spuIrq1=spuIrq2[1];
|
|
||||||
if(pSpuIrq[1]) pFO->pSpuIrq1 = (unsigned long)pSpuIrq[1]-(unsigned long)spuMemC;
|
|
||||||
|
|
||||||
for(i=0;i<MAXCHAN;i++)
|
|
||||||
{
|
|
||||||
memcpy((void *)&pFO->s_chan[i],(void *)&s_chan[i],sizeof(SPUCHAN));
|
|
||||||
if(pFO->s_chan[i].pStart)
|
|
||||||
pFO->s_chan[i].pStart-=(unsigned long)spuMemC;
|
|
||||||
if(pFO->s_chan[i].pCurr)
|
|
||||||
pFO->s_chan[i].pCurr-=(unsigned long)spuMemC;
|
|
||||||
if(pFO->s_chan[i].pLoop)
|
|
||||||
pFO->s_chan[i].pLoop-=(unsigned long)spuMemC;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetupTimer(); // sound processing on again
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
//--------------------------------------------------//
|
|
||||||
}
|
|
||||||
|
|
||||||
// load state:
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode==1 && IsWindow(hWDebug)) // we have to disbale the debug window, if active
|
|
||||||
DestroyWindow(hWDebug);
|
|
||||||
hWDebug=0;
|
|
||||||
|
|
||||||
if(IsBadReadPtr(pFt,sizeof(SPUFreeze_t))) // check bad emu stuff
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(pFt->size!=sizeof(SPUFreeze_Ex_t)+ // not our stuff? bye
|
|
||||||
sizeof(SPUOSSFreeze_t)) return 0;
|
|
||||||
if(!pFt->data) return 0;
|
|
||||||
|
|
||||||
pF=(SPUFreeze_Ex_t *)pFt->data;
|
|
||||||
|
|
||||||
RemoveTimer(); // we stop processing while doing the save!
|
|
||||||
|
|
||||||
memcpy(spuMem,pF->cSPURam,2*1024*1024); // get ram
|
|
||||||
memcpy(regArea,pF->cSPUPort,64*1024);
|
|
||||||
|
|
||||||
if(!strcmp(pF->szSPUName,"PBOSS2") &&
|
|
||||||
pF->ulFreezeVersion==1)
|
|
||||||
LoadStateV1(pF);
|
|
||||||
else LoadStateUnknown(pF);
|
|
||||||
|
|
||||||
// repair some globals
|
|
||||||
for(i=0x7FFE;i>=0x0000;i-=2)
|
|
||||||
{
|
|
||||||
SPU2write(i,regArea[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix to prevent new interpolations from crashing
|
|
||||||
for(i=0;i<MAXCHAN;i++) s_chan[i].SB[28]=0;
|
|
||||||
|
|
||||||
SetupTimer(); // start sound processing again
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
if(iDebugMode) // re-activate windows debug dialog
|
|
||||||
{
|
|
||||||
hWDebug=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DEBUG),
|
|
||||||
NULL,(DLGPROC)DebugDlgProc);
|
|
||||||
SetWindowPos(hWDebug,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE);
|
|
||||||
UpdateWindow(hWDebug);
|
|
||||||
SetFocus(hWMain);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void LoadStateV1(SPUFreeze_Ex_t * pF)
|
|
||||||
{
|
|
||||||
int i;SPUOSSFreeze_t * pFO;
|
|
||||||
|
|
||||||
pFO=(SPUOSSFreeze_t *)(pF+1);
|
|
||||||
|
|
||||||
spuIrq2[0] = pFO->spuIrq0;
|
|
||||||
if(pFO->pSpuIrq0) pSpuIrq[0] = pFO->pSpuIrq0+spuMemC; else pSpuIrq[0]=0;
|
|
||||||
spuIrq2[1] = pFO->spuIrq1;
|
|
||||||
if(pFO->pSpuIrq1) pSpuIrq[1] = pFO->pSpuIrq1+spuMemC; else pSpuIrq[1]=0;
|
|
||||||
|
|
||||||
for(i=0;i<MAXCHAN;i++)
|
|
||||||
{
|
|
||||||
memcpy((void *)&s_chan[i],(void *)&pFO->s_chan[i],sizeof(SPUCHAN));
|
|
||||||
|
|
||||||
s_chan[i].pStart+=(unsigned long)spuMemC;
|
|
||||||
s_chan[i].pCurr+=(unsigned long)spuMemC;
|
|
||||||
s_chan[i].pLoop+=(unsigned long)spuMemC;
|
|
||||||
s_chan[i].iMute=0;
|
|
||||||
s_chan[i].iIrqDone=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void LoadStateUnknown(SPUFreeze_Ex_t * pF)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0;i<MAXCHAN;i++)
|
|
||||||
{
|
|
||||||
s_chan[i].bOn=0;
|
|
||||||
s_chan[i].bNew=0;
|
|
||||||
s_chan[i].bStop=0;
|
|
||||||
s_chan[i].ADSR.lVolume=0;
|
|
||||||
s_chan[i].pLoop=spuMemC;
|
|
||||||
s_chan[i].pStart=spuMemC;
|
|
||||||
s_chan[i].iMute=0;
|
|
||||||
s_chan[i].iIrqDone=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dwNewChannel2[0]=0;
|
|
||||||
dwNewChannel2[1]=0;
|
|
||||||
dwEndChannel2[0]=0;
|
|
||||||
dwEndChannel2[1]=0;
|
|
||||||
|
|
||||||
pSpuIrq[0]=0;
|
|
||||||
pSpuIrq[1]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
|
@ -1,162 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
gauss_i.h - description
|
|
||||||
-----------------------
|
|
||||||
begin : Sun Feb 08 2003
|
|
||||||
copyright : (C) 2003 by Chris Moeller, eh, whatever
|
|
||||||
email : chris@kode54.tk
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2003/02/08 - kode54
|
|
||||||
// - generated by interleaving table from gauss.h from the libopenspc
|
|
||||||
// project; a gaussian bell curve table logged from the SPC-700,
|
|
||||||
// though Neill says he logged the same curve from a PSX SPU. Also
|
|
||||||
// says that interleaving the coefficients together runs faster. Meh.
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#ifndef GAUSS_H
|
|
||||||
#define GAUSS_H
|
|
||||||
|
|
||||||
const int gauss[]={
|
|
||||||
0x172, 0x519, 0x176, 0x000, 0x16E, 0x519, 0x17A, 0x000,
|
|
||||||
0x16A, 0x518, 0x17D, 0x000, 0x166, 0x518, 0x181, 0x000,
|
|
||||||
0x162, 0x518, 0x185, 0x000, 0x15F, 0x518, 0x189, 0x000,
|
|
||||||
0x15B, 0x518, 0x18D, 0x000, 0x157, 0x517, 0x191, 0x000,
|
|
||||||
0x153, 0x517, 0x195, 0x000, 0x150, 0x517, 0x19A, 0x000,
|
|
||||||
0x14C, 0x516, 0x19E, 0x000, 0x148, 0x516, 0x1A2, 0x000,
|
|
||||||
0x145, 0x515, 0x1A6, 0x000, 0x141, 0x514, 0x1AA, 0x000,
|
|
||||||
0x13E, 0x514, 0x1AE, 0x000, 0x13A, 0x513, 0x1B2, 0x000,
|
|
||||||
0x137, 0x512, 0x1B7, 0x001, 0x133, 0x511, 0x1BB, 0x001,
|
|
||||||
0x130, 0x511, 0x1BF, 0x001, 0x12C, 0x510, 0x1C3, 0x001,
|
|
||||||
0x129, 0x50F, 0x1C8, 0x001, 0x125, 0x50E, 0x1CC, 0x001,
|
|
||||||
0x122, 0x50D, 0x1D0, 0x001, 0x11E, 0x50C, 0x1D5, 0x001,
|
|
||||||
0x11B, 0x50B, 0x1D9, 0x001, 0x118, 0x50A, 0x1DD, 0x001,
|
|
||||||
0x114, 0x508, 0x1E2, 0x001, 0x111, 0x507, 0x1E6, 0x002,
|
|
||||||
0x10E, 0x506, 0x1EB, 0x002, 0x10B, 0x504, 0x1EF, 0x002,
|
|
||||||
0x107, 0x503, 0x1F3, 0x002, 0x104, 0x502, 0x1F8, 0x002,
|
|
||||||
0x101, 0x500, 0x1FC, 0x002, 0x0FE, 0x4FF, 0x201, 0x002,
|
|
||||||
0x0FB, 0x4FD, 0x205, 0x003, 0x0F8, 0x4FB, 0x20A, 0x003,
|
|
||||||
0x0F5, 0x4FA, 0x20F, 0x003, 0x0F2, 0x4F8, 0x213, 0x003,
|
|
||||||
0x0EF, 0x4F6, 0x218, 0x003, 0x0EC, 0x4F5, 0x21C, 0x004,
|
|
||||||
0x0E9, 0x4F3, 0x221, 0x004, 0x0E6, 0x4F1, 0x226, 0x004,
|
|
||||||
0x0E3, 0x4EF, 0x22A, 0x004, 0x0E0, 0x4ED, 0x22F, 0x004,
|
|
||||||
0x0DD, 0x4EB, 0x233, 0x005, 0x0DA, 0x4E9, 0x238, 0x005,
|
|
||||||
0x0D7, 0x4E7, 0x23D, 0x005, 0x0D4, 0x4E5, 0x241, 0x005,
|
|
||||||
0x0D2, 0x4E3, 0x246, 0x006, 0x0CF, 0x4E0, 0x24B, 0x006,
|
|
||||||
0x0CC, 0x4DE, 0x250, 0x006, 0x0C9, 0x4DC, 0x254, 0x006,
|
|
||||||
0x0C7, 0x4D9, 0x259, 0x007, 0x0C4, 0x4D7, 0x25E, 0x007,
|
|
||||||
0x0C1, 0x4D5, 0x263, 0x007, 0x0BF, 0x4D2, 0x267, 0x008,
|
|
||||||
0x0BC, 0x4D0, 0x26C, 0x008, 0x0BA, 0x4CD, 0x271, 0x008,
|
|
||||||
0x0B7, 0x4CB, 0x276, 0x009, 0x0B4, 0x4C8, 0x27B, 0x009,
|
|
||||||
0x0B2, 0x4C5, 0x280, 0x009, 0x0AF, 0x4C3, 0x284, 0x00A,
|
|
||||||
0x0AD, 0x4C0, 0x289, 0x00A, 0x0AB, 0x4BD, 0x28E, 0x00A,
|
|
||||||
0x0A8, 0x4BA, 0x293, 0x00B, 0x0A6, 0x4B7, 0x298, 0x00B,
|
|
||||||
0x0A3, 0x4B5, 0x29D, 0x00B, 0x0A1, 0x4B2, 0x2A2, 0x00C,
|
|
||||||
0x09F, 0x4AF, 0x2A6, 0x00C, 0x09C, 0x4AC, 0x2AB, 0x00D,
|
|
||||||
0x09A, 0x4A9, 0x2B0, 0x00D, 0x098, 0x4A6, 0x2B5, 0x00E,
|
|
||||||
0x096, 0x4A2, 0x2BA, 0x00E, 0x093, 0x49F, 0x2BF, 0x00F,
|
|
||||||
0x091, 0x49C, 0x2C4, 0x00F, 0x08F, 0x499, 0x2C9, 0x00F,
|
|
||||||
0x08D, 0x496, 0x2CE, 0x010, 0x08B, 0x492, 0x2D3, 0x010,
|
|
||||||
0x089, 0x48F, 0x2D8, 0x011, 0x086, 0x48C, 0x2DC, 0x011,
|
|
||||||
0x084, 0x488, 0x2E1, 0x012, 0x082, 0x485, 0x2E6, 0x013,
|
|
||||||
0x080, 0x481, 0x2EB, 0x013, 0x07E, 0x47E, 0x2F0, 0x014,
|
|
||||||
0x07C, 0x47A, 0x2F5, 0x014, 0x07A, 0x477, 0x2FA, 0x015,
|
|
||||||
0x078, 0x473, 0x2FF, 0x015, 0x076, 0x470, 0x304, 0x016,
|
|
||||||
0x075, 0x46C, 0x309, 0x017, 0x073, 0x468, 0x30E, 0x017,
|
|
||||||
0x071, 0x465, 0x313, 0x018, 0x06F, 0x461, 0x318, 0x018,
|
|
||||||
0x06D, 0x45D, 0x31D, 0x019, 0x06B, 0x459, 0x322, 0x01A,
|
|
||||||
0x06A, 0x455, 0x326, 0x01B, 0x068, 0x452, 0x32B, 0x01B,
|
|
||||||
0x066, 0x44E, 0x330, 0x01C, 0x064, 0x44A, 0x335, 0x01D,
|
|
||||||
0x063, 0x446, 0x33A, 0x01D, 0x061, 0x442, 0x33F, 0x01E,
|
|
||||||
0x05F, 0x43E, 0x344, 0x01F, 0x05E, 0x43A, 0x349, 0x020,
|
|
||||||
0x05C, 0x436, 0x34E, 0x020, 0x05A, 0x432, 0x353, 0x021,
|
|
||||||
0x059, 0x42E, 0x357, 0x022, 0x057, 0x42A, 0x35C, 0x023,
|
|
||||||
0x056, 0x425, 0x361, 0x024, 0x054, 0x421, 0x366, 0x024,
|
|
||||||
0x053, 0x41D, 0x36B, 0x025, 0x051, 0x419, 0x370, 0x026,
|
|
||||||
0x050, 0x415, 0x374, 0x027, 0x04E, 0x410, 0x379, 0x028,
|
|
||||||
0x04D, 0x40C, 0x37E, 0x029, 0x04C, 0x408, 0x383, 0x02A,
|
|
||||||
0x04A, 0x403, 0x388, 0x02B, 0x049, 0x3FF, 0x38C, 0x02C,
|
|
||||||
0x047, 0x3FB, 0x391, 0x02D, 0x046, 0x3F6, 0x396, 0x02E,
|
|
||||||
0x045, 0x3F2, 0x39B, 0x02F, 0x043, 0x3ED, 0x39F, 0x030,
|
|
||||||
0x042, 0x3E9, 0x3A4, 0x031, 0x041, 0x3E5, 0x3A9, 0x032,
|
|
||||||
0x040, 0x3E0, 0x3AD, 0x033, 0x03E, 0x3DC, 0x3B2, 0x034,
|
|
||||||
0x03D, 0x3D7, 0x3B7, 0x035, 0x03C, 0x3D2, 0x3BB, 0x036,
|
|
||||||
0x03B, 0x3CE, 0x3C0, 0x037, 0x03A, 0x3C9, 0x3C5, 0x038,
|
|
||||||
0x038, 0x3C5, 0x3C9, 0x03A, 0x037, 0x3C0, 0x3CE, 0x03B,
|
|
||||||
0x036, 0x3BB, 0x3D2, 0x03C, 0x035, 0x3B7, 0x3D7, 0x03D,
|
|
||||||
0x034, 0x3B2, 0x3DC, 0x03E, 0x033, 0x3AD, 0x3E0, 0x040,
|
|
||||||
0x032, 0x3A9, 0x3E5, 0x041, 0x031, 0x3A4, 0x3E9, 0x042,
|
|
||||||
0x030, 0x39F, 0x3ED, 0x043, 0x02F, 0x39B, 0x3F2, 0x045,
|
|
||||||
0x02E, 0x396, 0x3F6, 0x046, 0x02D, 0x391, 0x3FB, 0x047,
|
|
||||||
0x02C, 0x38C, 0x3FF, 0x049, 0x02B, 0x388, 0x403, 0x04A,
|
|
||||||
0x02A, 0x383, 0x408, 0x04C, 0x029, 0x37E, 0x40C, 0x04D,
|
|
||||||
0x028, 0x379, 0x410, 0x04E, 0x027, 0x374, 0x415, 0x050,
|
|
||||||
0x026, 0x370, 0x419, 0x051, 0x025, 0x36B, 0x41D, 0x053,
|
|
||||||
0x024, 0x366, 0x421, 0x054, 0x024, 0x361, 0x425, 0x056,
|
|
||||||
0x023, 0x35C, 0x42A, 0x057, 0x022, 0x357, 0x42E, 0x059,
|
|
||||||
0x021, 0x353, 0x432, 0x05A, 0x020, 0x34E, 0x436, 0x05C,
|
|
||||||
0x020, 0x349, 0x43A, 0x05E, 0x01F, 0x344, 0x43E, 0x05F,
|
|
||||||
0x01E, 0x33F, 0x442, 0x061, 0x01D, 0x33A, 0x446, 0x063,
|
|
||||||
0x01D, 0x335, 0x44A, 0x064, 0x01C, 0x330, 0x44E, 0x066,
|
|
||||||
0x01B, 0x32B, 0x452, 0x068, 0x01B, 0x326, 0x455, 0x06A,
|
|
||||||
0x01A, 0x322, 0x459, 0x06B, 0x019, 0x31D, 0x45D, 0x06D,
|
|
||||||
0x018, 0x318, 0x461, 0x06F, 0x018, 0x313, 0x465, 0x071,
|
|
||||||
0x017, 0x30E, 0x468, 0x073, 0x017, 0x309, 0x46C, 0x075,
|
|
||||||
0x016, 0x304, 0x470, 0x076, 0x015, 0x2FF, 0x473, 0x078,
|
|
||||||
0x015, 0x2FA, 0x477, 0x07A, 0x014, 0x2F5, 0x47A, 0x07C,
|
|
||||||
0x014, 0x2F0, 0x47E, 0x07E, 0x013, 0x2EB, 0x481, 0x080,
|
|
||||||
0x013, 0x2E6, 0x485, 0x082, 0x012, 0x2E1, 0x488, 0x084,
|
|
||||||
0x011, 0x2DC, 0x48C, 0x086, 0x011, 0x2D8, 0x48F, 0x089,
|
|
||||||
0x010, 0x2D3, 0x492, 0x08B, 0x010, 0x2CE, 0x496, 0x08D,
|
|
||||||
0x00F, 0x2C9, 0x499, 0x08F, 0x00F, 0x2C4, 0x49C, 0x091,
|
|
||||||
0x00F, 0x2BF, 0x49F, 0x093, 0x00E, 0x2BA, 0x4A2, 0x096,
|
|
||||||
0x00E, 0x2B5, 0x4A6, 0x098, 0x00D, 0x2B0, 0x4A9, 0x09A,
|
|
||||||
0x00D, 0x2AB, 0x4AC, 0x09C, 0x00C, 0x2A6, 0x4AF, 0x09F,
|
|
||||||
0x00C, 0x2A2, 0x4B2, 0x0A1, 0x00B, 0x29D, 0x4B5, 0x0A3,
|
|
||||||
0x00B, 0x298, 0x4B7, 0x0A6, 0x00B, 0x293, 0x4BA, 0x0A8,
|
|
||||||
0x00A, 0x28E, 0x4BD, 0x0AB, 0x00A, 0x289, 0x4C0, 0x0AD,
|
|
||||||
0x00A, 0x284, 0x4C3, 0x0AF, 0x009, 0x280, 0x4C5, 0x0B2,
|
|
||||||
0x009, 0x27B, 0x4C8, 0x0B4, 0x009, 0x276, 0x4CB, 0x0B7,
|
|
||||||
0x008, 0x271, 0x4CD, 0x0BA, 0x008, 0x26C, 0x4D0, 0x0BC,
|
|
||||||
0x008, 0x267, 0x4D2, 0x0BF, 0x007, 0x263, 0x4D5, 0x0C1,
|
|
||||||
0x007, 0x25E, 0x4D7, 0x0C4, 0x007, 0x259, 0x4D9, 0x0C7,
|
|
||||||
0x006, 0x254, 0x4DC, 0x0C9, 0x006, 0x250, 0x4DE, 0x0CC,
|
|
||||||
0x006, 0x24B, 0x4E0, 0x0CF, 0x006, 0x246, 0x4E3, 0x0D2,
|
|
||||||
0x005, 0x241, 0x4E5, 0x0D4, 0x005, 0x23D, 0x4E7, 0x0D7,
|
|
||||||
0x005, 0x238, 0x4E9, 0x0DA, 0x005, 0x233, 0x4EB, 0x0DD,
|
|
||||||
0x004, 0x22F, 0x4ED, 0x0E0, 0x004, 0x22A, 0x4EF, 0x0E3,
|
|
||||||
0x004, 0x226, 0x4F1, 0x0E6, 0x004, 0x221, 0x4F3, 0x0E9,
|
|
||||||
0x004, 0x21C, 0x4F5, 0x0EC, 0x003, 0x218, 0x4F6, 0x0EF,
|
|
||||||
0x003, 0x213, 0x4F8, 0x0F2, 0x003, 0x20F, 0x4FA, 0x0F5,
|
|
||||||
0x003, 0x20A, 0x4FB, 0x0F8, 0x003, 0x205, 0x4FD, 0x0FB,
|
|
||||||
0x002, 0x201, 0x4FF, 0x0FE, 0x002, 0x1FC, 0x500, 0x101,
|
|
||||||
0x002, 0x1F8, 0x502, 0x104, 0x002, 0x1F3, 0x503, 0x107,
|
|
||||||
0x002, 0x1EF, 0x504, 0x10B, 0x002, 0x1EB, 0x506, 0x10E,
|
|
||||||
0x002, 0x1E6, 0x507, 0x111, 0x001, 0x1E2, 0x508, 0x114,
|
|
||||||
0x001, 0x1DD, 0x50A, 0x118, 0x001, 0x1D9, 0x50B, 0x11B,
|
|
||||||
0x001, 0x1D5, 0x50C, 0x11E, 0x001, 0x1D0, 0x50D, 0x122,
|
|
||||||
0x001, 0x1CC, 0x50E, 0x125, 0x001, 0x1C8, 0x50F, 0x129,
|
|
||||||
0x001, 0x1C3, 0x510, 0x12C, 0x001, 0x1BF, 0x511, 0x130,
|
|
||||||
0x001, 0x1BB, 0x511, 0x133, 0x001, 0x1B7, 0x512, 0x137,
|
|
||||||
0x000, 0x1B2, 0x513, 0x13A, 0x000, 0x1AE, 0x514, 0x13E,
|
|
||||||
0x000, 0x1AA, 0x514, 0x141, 0x000, 0x1A6, 0x515, 0x145,
|
|
||||||
0x000, 0x1A2, 0x516, 0x148, 0x000, 0x19E, 0x516, 0x14C,
|
|
||||||
0x000, 0x19A, 0x517, 0x150, 0x000, 0x195, 0x517, 0x153,
|
|
||||||
0x000, 0x191, 0x517, 0x157, 0x000, 0x18D, 0x518, 0x15B,
|
|
||||||
0x000, 0x189, 0x518, 0x15F, 0x000, 0x185, 0x518, 0x162,
|
|
||||||
0x000, 0x181, 0x518, 0x166, 0x000, 0x17D, 0x518, 0x16A,
|
|
||||||
0x000, 0x17A, 0x519, 0x16E, 0x000, 0x176, 0x519, 0x172};
|
|
||||||
#endif
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include <windows.h>
|
|
||||||
#define IDC_STATIC -1
|
|
|
@ -1,190 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
oss.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2005/08/29 - Pete
|
|
||||||
// - changed to 48Khz output
|
|
||||||
//
|
|
||||||
// 2003/03/01 - linuzappz
|
|
||||||
// - added checkings for oss_audio_fd == -1
|
|
||||||
//
|
|
||||||
// 2003/02/08 - linuzappz
|
|
||||||
// - added iDisStereo stuff
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_OSS
|
|
||||||
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// small linux time helper... only used for watchdog
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <sys/timeb.h>
|
|
||||||
|
|
||||||
extern unsigned int timeGetTime()
|
|
||||||
{
|
|
||||||
struct timeb t;
|
|
||||||
ftime(&t);
|
|
||||||
return (unsigned int)(t.time*1000+t.millitm);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// oss globals
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define OSS_MEM_DEF
|
|
||||||
#include "oss.h"
|
|
||||||
static int oss_audio_fd = -1;
|
|
||||||
extern int errno;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// SETUP SOUND
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SetupSound(void)
|
|
||||||
{
|
|
||||||
int pspeed=48000;
|
|
||||||
int pstereo;
|
|
||||||
int format;
|
|
||||||
int fragsize = 0;
|
|
||||||
int myfrag;
|
|
||||||
int oss_speed, oss_stereo;
|
|
||||||
|
|
||||||
if(iDisStereo) pstereo=OSS_MODE_MONO;
|
|
||||||
else pstereo=OSS_MODE_STEREO;
|
|
||||||
|
|
||||||
oss_speed = pspeed;
|
|
||||||
oss_stereo = pstereo;
|
|
||||||
|
|
||||||
if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1)
|
|
||||||
{
|
|
||||||
printf("Sound device not available!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1)
|
|
||||||
{
|
|
||||||
printf("Sound reset failed\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we use 64 fragments with 1024 bytes each
|
|
||||||
|
|
||||||
fragsize=10;
|
|
||||||
myfrag=(63<<16)|fragsize;
|
|
||||||
|
|
||||||
if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
|
|
||||||
{
|
|
||||||
printf("Sound set fragment failed!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
format = AFMT_S16_LE;
|
|
||||||
|
|
||||||
if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
|
|
||||||
{
|
|
||||||
printf("Sound format not supported!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(format!=AFMT_S16_LE)
|
|
||||||
{
|
|
||||||
printf("Sound format not supported!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1)
|
|
||||||
{
|
|
||||||
printf("Stereo mode not supported!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(oss_stereo!=1)
|
|
||||||
{
|
|
||||||
iDisStereo=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
|
|
||||||
{
|
|
||||||
printf("Sound frequency not supported\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(oss_speed!=pspeed)
|
|
||||||
{
|
|
||||||
printf("Sound frequency not supported\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// REMOVE SOUND
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void RemoveSound(void)
|
|
||||||
{
|
|
||||||
if(oss_audio_fd != -1 )
|
|
||||||
{
|
|
||||||
close(oss_audio_fd);
|
|
||||||
oss_audio_fd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// GET BYTES BUFFERED
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
unsigned long SoundGetBytesBuffered(void)
|
|
||||||
{
|
|
||||||
audio_buf_info info;
|
|
||||||
unsigned long l;
|
|
||||||
|
|
||||||
if(oss_audio_fd == -1) return SOUNDSIZE;
|
|
||||||
if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
|
|
||||||
l=0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(info.fragments<(info.fragstotal>>1)) // can we write in at least the half of fragments?
|
|
||||||
l=SOUNDSIZE; // -> no? wait
|
|
||||||
else l=0; // -> else go on
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// FEED SOUND DATA
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SoundFeedVoiceData(unsigned char* pSound,long lBytes)
|
|
||||||
{
|
|
||||||
if(oss_audio_fd == -1) return;
|
|
||||||
write(oss_audio_fd,pSound,lBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,37 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
oss_sound.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed Dec 8 1999
|
|
||||||
copyright : (C) 1999 by Marcin "Duddie" Dudar
|
|
||||||
email : duddie@psemu.com
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _OSS_SOUND_H
|
|
||||||
#define _OSS_SOUND_H
|
|
||||||
|
|
||||||
#ifdef OSS_MEM_DEF
|
|
||||||
#define OSS_MEM_EXTERN
|
|
||||||
#else
|
|
||||||
#define OSS_MEM_EXTERN extern
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OSS_MEM_EXTERN int sound_buffer_size;
|
|
||||||
|
|
||||||
#define OSS_MODE_STEREO 1
|
|
||||||
#define OSS_MODE_MONO 0
|
|
||||||
|
|
||||||
#define OSS_SPEED_44100 44100
|
|
||||||
|
|
||||||
void SoundFeedVoiceData(unsigned char* pSound,long lBytes);
|
|
||||||
|
|
||||||
#endif // _OSS_SOUND_H
|
|
|
@ -1,28 +0,0 @@
|
||||||
//============================================
|
|
||||||
//=== Audio XA decoding
|
|
||||||
//=== Kazzuya
|
|
||||||
//============================================
|
|
||||||
|
|
||||||
#ifndef DECODEXA_H
|
|
||||||
#define DECODEXA_H
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
long y0, y1;
|
|
||||||
} ADPCM_Decode_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int freq;
|
|
||||||
int nbits;
|
|
||||||
int stereo;
|
|
||||||
int nsamples;
|
|
||||||
ADPCM_Decode_t left, right;
|
|
||||||
short pcm[16384];
|
|
||||||
} xa_decode_t;
|
|
||||||
|
|
||||||
long xa_decode_sector( xa_decode_t *xdp,
|
|
||||||
unsigned char *sectorp,
|
|
||||||
int is_first_sector );
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,184 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
spu.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Sun Jan 12 2003
|
|
||||||
copyright : (C) 2003 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2005/08/29 - Pete
|
|
||||||
// - changed to 48Khz output
|
|
||||||
//
|
|
||||||
// 2003/03/01 - Pete
|
|
||||||
// - added mono mode
|
|
||||||
//
|
|
||||||
// 2003/01/12 - Pete
|
|
||||||
// - added recording funcs (win version only)
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
|
|
||||||
#include <mmsystem.h>
|
|
||||||
#include "resource.h"
|
|
||||||
#include "externals.h"
|
|
||||||
|
|
||||||
#define _IN_RECORD
|
|
||||||
|
|
||||||
#include "record.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int iDoRecord=0;
|
|
||||||
HMMIO hWaveFile=NULL;
|
|
||||||
MMCKINFO mmckMain;
|
|
||||||
MMCKINFO mmckData;
|
|
||||||
char szFileName[256]={"C:\\PEOPS.WAV"};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void RecordStart()
|
|
||||||
{
|
|
||||||
WAVEFORMATEX pcmwf;
|
|
||||||
|
|
||||||
// setup header in the same format as our directsound stream
|
|
||||||
memset(&pcmwf,0,sizeof(WAVEFORMATEX));
|
|
||||||
pcmwf.wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
|
|
||||||
pcmwf.nChannels = 2;
|
|
||||||
pcmwf.nBlockAlign = 4;
|
|
||||||
|
|
||||||
pcmwf.nSamplesPerSec = 48000;
|
|
||||||
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
|
|
||||||
pcmwf.wBitsPerSample = 16;
|
|
||||||
|
|
||||||
// create file
|
|
||||||
hWaveFile=mmioOpen(szFileName,NULL,MMIO_CREATE|MMIO_WRITE|MMIO_EXCLUSIVE | MMIO_ALLOCBUF);
|
|
||||||
if(!hWaveFile) return;
|
|
||||||
|
|
||||||
// setup WAVE, fmt and data chunks
|
|
||||||
memset(&mmckMain,0,sizeof(MMCKINFO));
|
|
||||||
mmckMain.fccType = mmioFOURCC('W','A','V','E');
|
|
||||||
|
|
||||||
mmioCreateChunk(hWaveFile,&mmckMain,MMIO_CREATERIFF);
|
|
||||||
|
|
||||||
memset(&mmckData,0,sizeof(MMCKINFO));
|
|
||||||
mmckData.ckid = mmioFOURCC('f','m','t',' ');
|
|
||||||
mmckData.cksize = sizeof(WAVEFORMATEX);
|
|
||||||
|
|
||||||
mmioCreateChunk(hWaveFile,&mmckData,0);
|
|
||||||
mmioWrite(hWaveFile,(char*)&pcmwf,sizeof(WAVEFORMATEX));
|
|
||||||
mmioAscend(hWaveFile,&mmckData,0);
|
|
||||||
|
|
||||||
mmckData.ckid = mmioFOURCC('d','a','t','a');
|
|
||||||
mmioCreateChunk(hWaveFile,&mmckData,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void RecordStop()
|
|
||||||
{
|
|
||||||
// first some check, if recording is running
|
|
||||||
iDoRecord=0;
|
|
||||||
if(!hWaveFile) return;
|
|
||||||
|
|
||||||
// now finish writing & close the wave file
|
|
||||||
mmioAscend(hWaveFile,&mmckData,0);
|
|
||||||
mmioAscend(hWaveFile,&mmckMain,0);
|
|
||||||
mmioClose(hWaveFile,0);
|
|
||||||
|
|
||||||
// init var
|
|
||||||
hWaveFile=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void RecordBuffer(unsigned char* pSound,long lBytes)
|
|
||||||
{
|
|
||||||
// write the samples
|
|
||||||
if(hWaveFile) mmioWrite(hWaveFile,pSound,lBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL CALLBACK RecordDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch(uMsg)
|
|
||||||
{
|
|
||||||
//--------------------------------------------------// init
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
{
|
|
||||||
SetDlgItemText(hW,IDC_WAVFILE,szFileName); // init filename edit
|
|
||||||
ShowCursor(TRUE); // mmm... who is hiding it? main emu? tsts
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------// destroy
|
|
||||||
case WM_DESTROY:
|
|
||||||
{
|
|
||||||
RecordStop();
|
|
||||||
}break;
|
|
||||||
//--------------------------------------------------// command
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
|
||||||
if(wParam==IDCANCEL) iRecordMode=2; // cancel? raise flag for destroying the dialog
|
|
||||||
|
|
||||||
if(wParam==IDC_RECORD) // record start/stop?
|
|
||||||
{
|
|
||||||
if(IsWindowEnabled(GetDlgItem(hW,IDC_WAVFILE))) // not started yet (edit is not disabled):
|
|
||||||
{
|
|
||||||
GetDlgItemText(hW,IDC_WAVFILE,szFileName,255);// get filename
|
|
||||||
|
|
||||||
RecordStart(); // start recording
|
|
||||||
|
|
||||||
if(hWaveFile) // start was ok?
|
|
||||||
{ // -> disable filename edit, change text, raise flag
|
|
||||||
EnableWindow(GetDlgItem(hW,IDC_WAVFILE),FALSE);
|
|
||||||
SetDlgItemText(hW,IDC_RECORD,"Stop recording");
|
|
||||||
iDoRecord=1;
|
|
||||||
}
|
|
||||||
else MessageBeep(0xFFFFFFFF); // error starting recording? BEEP
|
|
||||||
}
|
|
||||||
else // stop recording?
|
|
||||||
{
|
|
||||||
RecordStop(); // -> just do it
|
|
||||||
EnableWindow(GetDlgItem(hW,IDC_WAVFILE),TRUE);// -> enable filename edit again
|
|
||||||
SetDlgItemText(hW,IDC_RECORD,"Start recording");
|
|
||||||
}
|
|
||||||
SetFocus(hWMain);
|
|
||||||
}
|
|
||||||
|
|
||||||
}break;
|
|
||||||
//--------------------------------------------------// size
|
|
||||||
case WM_SIZE:
|
|
||||||
if(wParam==SIZE_MINIMIZED) SetFocus(hWMain); // if we get minimized, set the foxus to the main window
|
|
||||||
break;
|
|
||||||
//--------------------------------------------------// setcursor
|
|
||||||
case WM_SETCURSOR:
|
|
||||||
{
|
|
||||||
SetCursor(LoadCursor(NULL,IDC_ARROW)); // force the arrow
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------//
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif
|
|
|
@ -1,12 +0,0 @@
|
||||||
#ifndef _RECORD_H_
|
|
||||||
#define _RECORD_H_
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
void RecordStart();
|
|
||||||
void RecordBuffer(unsigned char* pSound,long lBytes);
|
|
||||||
void RecordStop();
|
|
||||||
BOOL CALLBACK RecordDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,820 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
registers.h - description
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - generic cleanup for the Peops release... register values by Kanodin &
|
|
||||||
// his team
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
//###########################################################################
|
|
||||||
|
|
||||||
#define PS2_C0_SPUaddr_Hi (0x1A8)
|
|
||||||
#define PS2_C0_SPUaddr_Lo (0x1AA)
|
|
||||||
#define PS2_C1_SPUaddr_Hi (0x5A8)
|
|
||||||
#define PS2_C1_SPUaddr_Lo (0x5AA)
|
|
||||||
#define PS2_C0_SPUdata (0x1AC)
|
|
||||||
#define PS2_C1_SPUdata (0x5AC)
|
|
||||||
|
|
||||||
#define PS2_C0_SPUDMActrl (0x1AE)
|
|
||||||
#define PS2_C1_SPUDMActrl (0x5AE)
|
|
||||||
|
|
||||||
#define PS2_C0_SPUstat (0x344)
|
|
||||||
#define PS2_C1_SPUstat (0x744)
|
|
||||||
#define PS2_IRQINFO (0x7C2)
|
|
||||||
#define PS2_C0_ReverbAddr_Hi (0x2E0)
|
|
||||||
#define PS2_C0_ReverbAddr_Lo (0x2E2)
|
|
||||||
#define PS2_C1_ReverbAddr_Hi (0x6E0)
|
|
||||||
#define PS2_C1_ReverbAddr_Lo (0x6E2)
|
|
||||||
|
|
||||||
#define PS2_C0_ReverbAEnd_Hi (0x33C)
|
|
||||||
#define PS2_C0_ReverbAEnd_Lo (0x33E)
|
|
||||||
#define PS2_C1_ReverbAEnd_Hi (0x73C)
|
|
||||||
#define PS2_C1_ReverbAEnd_Lo (0x73E)
|
|
||||||
|
|
||||||
#define PS2_C0_DryL1 (0x188)
|
|
||||||
#define PS2_C1_DryL1 (0x588)
|
|
||||||
#define PS2_C0_DryL2 (0x18A)
|
|
||||||
#define PS2_C1_DryL2 (0x58A)
|
|
||||||
|
|
||||||
#define PS2_C0_DryR1 (0x190)
|
|
||||||
#define PS2_C1_DryR1 (0x590)
|
|
||||||
#define PS2_C0_DryR2 (0x192)
|
|
||||||
#define PS2_C1_DryR2 (0x592)
|
|
||||||
|
|
||||||
#define PS2_C0_ATTR (0x19A)
|
|
||||||
#define PS2_C1_ATTR (0x59A)
|
|
||||||
#define PS2_C0_ADMAS (0x1B0)
|
|
||||||
#define PS2_C1_ADMAS (0x5B0)
|
|
||||||
|
|
||||||
#define PS2_C0_SPUirqAddr_Hi (0x19C)
|
|
||||||
#define PS2_C0_SPUirqAddr_Lo (0x19E)
|
|
||||||
#define PS2_C1_SPUirqAddr_Hi (0x59C)
|
|
||||||
#define PS2_C1_SPUirqAddr_Lo (0x59E)
|
|
||||||
#define PS2_C0_SPUrvolL (0x764)
|
|
||||||
#define PS2_C0_SPUrvolR (0x766)
|
|
||||||
#define PS2_C1_SPUrvolL (0x028 + 0x764)
|
|
||||||
#define PS2_C1_SPUrvolR (0x028 + 0x766)
|
|
||||||
#define PS2_C0_SPUon1 (0x1A0)
|
|
||||||
#define PS2_C0_SPUon2 (0x1A2)
|
|
||||||
#define PS2_C1_SPUon1 (0x5A0)
|
|
||||||
#define PS2_C1_SPUon2 (0x5A2)
|
|
||||||
#define PS2_C0_SPUoff1 (0x1A4)
|
|
||||||
#define PS2_C0_SPUoff2 (0x1A6)
|
|
||||||
#define PS2_C1_SPUoff1 (0x5A4)
|
|
||||||
#define PS2_C1_SPUoff2 (0x5A6)
|
|
||||||
#define PS2_C0_FMod1 (0x180)
|
|
||||||
#define PS2_C0_FMod2 (0x182)
|
|
||||||
#define PS2_C1_FMod1 (0x580)
|
|
||||||
#define PS2_C1_FMod2 (0x582)
|
|
||||||
#define PS2_C0_Noise1 (0x184)
|
|
||||||
#define PS2_C0_Noise2 (0x186)
|
|
||||||
#define PS2_C1_Noise1 (0x584)
|
|
||||||
#define PS2_C1_Noise2 (0x586)
|
|
||||||
|
|
||||||
#define PS2_C0_RVBon1_L (0x18C)
|
|
||||||
#define PS2_C0_RVBon2_L (0x18E)
|
|
||||||
#define PS2_C0_RVBon1_R (0x194)
|
|
||||||
#define PS2_C0_RVBon2_R (0x196)
|
|
||||||
|
|
||||||
#define PS2_C1_RVBon1_L (0x58C)
|
|
||||||
#define PS2_C1_RVBon2_L (0x58E)
|
|
||||||
#define PS2_C1_RVBon1_R (0x594)
|
|
||||||
#define PS2_C1_RVBon2_R (0x596)
|
|
||||||
#define PS2_C0_Reverb (0x2E4)
|
|
||||||
#define PS2_C1_Reverb (0x6E4)
|
|
||||||
#define PS2_C0_ReverbX (0x774)
|
|
||||||
#define PS2_C1_ReverbX (0x028 + 0x774)
|
|
||||||
#define PS2_C0_SPUend1 (0x340)
|
|
||||||
#define PS2_C0_SPUend2 (0x342)
|
|
||||||
#define PS2_C1_SPUend1 (0x740)
|
|
||||||
#define PS2_C1_SPUend2 (0x742)
|
|
||||||
#define PS2_C0_AVOLL (0x768) // Disabled really, but games read it
|
|
||||||
#define PS2_C0_AVOLR (0x76A) // In for logging purposes
|
|
||||||
#define PS2_C1_AVOLL (0x790) // core external input volume (left) core 1
|
|
||||||
#define PS2_C1_AVOLR (0x792) // core external input volume (right) core 1
|
|
||||||
#define PS2_C0_BVOLL (0x76C)
|
|
||||||
#define PS2_C0_BVOLR (0x76E)
|
|
||||||
#define PS2_C1_BVOLL (0x794)
|
|
||||||
#define PS2_C1_BVOLR (0x796)
|
|
||||||
#define PS2_C0_MMIX (0x198)
|
|
||||||
#define PS2_C1_MMIX (0x598)
|
|
||||||
|
|
||||||
#define PS2_C0_MVOLL (0x760)
|
|
||||||
#define PS2_C0_MVOLR (0x762)
|
|
||||||
#define PS2_C1_MVOLL (0x788)
|
|
||||||
#define PS2_C1_MVOLR (0x78A)
|
|
||||||
|
|
||||||
// CORE 1 only
|
|
||||||
|
|
||||||
#define PS2_SPDIF_OUT 0x7C0 // SPDIF Out: OFF/'PCM'/Bitstream/Bypass
|
|
||||||
#define PS2_SPDIF_MODE 0x7C6
|
|
||||||
#define PS2_SPDIF_MEDIA 0x7C8 // SPDIF Media: 'CD'/DVD
|
|
||||||
#define PS2_SPDIF_COPY 0x7CA // SPDIF Copy Protection
|
|
||||||
|
|
||||||
//###########################################################################
|
|
||||||
|
|
||||||
/*
|
|
||||||
Included the info received in Regs.txt list by Neill Corlett - Kanodin
|
|
||||||
|
|
||||||
Voice parameters:
|
|
||||||
SD_VP_VOLL, SD_VP_VOLR - Volume left/right per voice. Assuming identical to PS1.
|
|
||||||
SD_VP_PITCH - Pitch scaler 0000-3FFF. Assuming identical to PS1.
|
|
||||||
SD_VP_ADSR1, SD_VP_ADSR1 - Envelope data. Bitfields are documented as identical to PS1.
|
|
||||||
SD_VP_ENVX - Current envelope value. Assuming identical to PS1.
|
|
||||||
SD_VP_VOLXL, SD_VP_VOLXR - Current voice volume left/right. Does not exist on the PS1.
|
|
||||||
Guessing that this is handy for the increase/decrease modes.
|
|
||||||
|
|
||||||
Voice addresses:
|
|
||||||
|
|
||||||
SD_VA_SSA - Sample start address; assuming identical to PS1
|
|
||||||
SD_VA_LSAX - Loop start address; assuming identical to PS1
|
|
||||||
SD_VA_NAX - Seems to be documented as the current playing address.
|
|
||||||
Does not exist on PS1.
|
|
||||||
|
|
||||||
Switches:
|
|
||||||
|
|
||||||
SD_S_PMON - Pitch mod; assuming identical to PS1
|
|
||||||
SD_S_NON - Noise; assuming identical to PS1
|
|
||||||
SD_S_VMIXL, SD_S_VMIXR - Voice mix L/R. Guessing this is just a separate L/R version
|
|
||||||
of the "voice enable" bits on the PS1.
|
|
||||||
SD_S_VMIXEL, SD_S_VMIXER - Voice effect mix L/R. Guessing this is just a separate L/R
|
|
||||||
version of the "voice reverb enable" bits on the PS1.
|
|
||||||
SD_S_KON, SD_S_KOFF - Key on/off; assuming identical to PS1
|
|
||||||
|
|
||||||
|
|
||||||
Addresses:
|
|
||||||
|
|
||||||
SD_A_TSA - Transfer start address; assuming identical to PS1
|
|
||||||
SD_A_ESA - Effect start address - this is probably analogous to the
|
|
||||||
PS1's reverb work area start address
|
|
||||||
SD_A_EEA - Effect end address - this would've been fixed to 0x7FFFF on
|
|
||||||
the PS1; settable in 128K increments on the PS2.
|
|
||||||
SD_A_IRQA - IRQ address; assuming identical to PS1
|
|
||||||
|
|
||||||
Volume parameters:
|
|
||||||
|
|
||||||
SD_P_MVOLL, SD_P_MVOLR - Master volume L/R; assuming identical to PS1
|
|
||||||
SD_P_EVOLL, SD_P_EVOLR - Effect volume L/R; assuming analogous to RVOL on the PS1
|
|
||||||
SD_P_AVOLL, SD_P_AVOLR - External input volume L/R
|
|
||||||
This is probably where CORE0 connects to CORE1
|
|
||||||
SD_P_BVOLL, SD_P_BVOLR - Sound data input volume - perhaps this is the volume of
|
|
||||||
the raw PCM auto-DMA input? analogous to CD input volume?
|
|
||||||
SD_P_MVOLXL, SD_P_MVOLXR - Current master volume L/R; seems self-explanatory
|
|
||||||
|
|
||||||
SD_P_MMIX - Mixer / effect enable bits.
|
|
||||||
bit 11 = MSNDL = voice output dry L
|
|
||||||
10 = MSNDR = voice output dry R
|
|
||||||
9 = MSNDEL = voice output wet L
|
|
||||||
8 = MSNDER = voice output wet R
|
|
||||||
7 = MINL = sound data input dry L
|
|
||||||
6 = MINR = sound data input dry R
|
|
||||||
5 = MINEL = sound data input wet L
|
|
||||||
4 = MINER = sound data input wet R
|
|
||||||
3 = SINL = core external input dry L
|
|
||||||
2 = SINR = core external input dry R
|
|
||||||
1 = SINEL = core external input wet L
|
|
||||||
0 = SINER = core external input wet R
|
|
||||||
|
|
||||||
Core attributes (SD_C)
|
|
||||||
|
|
||||||
bit 4..5 - DMA related
|
|
||||||
bit 6 - IRQ enable
|
|
||||||
bit 7 - effect enable (reverb enable)
|
|
||||||
bit 13..8 - noise clock
|
|
||||||
bit 14 - mute
|
|
||||||
|
|
||||||
- if you READ the two DMA related bits, if either are set, the channel is
|
|
||||||
considered "busy" by sceSdVoiceTrans
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reverb parameters:
|
|
||||||
|
|
||||||
Same as PS1 reverb (I used the names from my reverb doc).
|
|
||||||
|
|
||||||
|
|
||||||
Other PS2 IOP notes
|
|
||||||
|
|
||||||
There's two DMA controllers:
|
|
||||||
The original one at 1F801080-1F8010FF (channels 0-6)
|
|
||||||
A new one at 1F801500-1F80157F (channels 7-13)
|
|
||||||
|
|
||||||
They appear to function the same way - 7 channels each.
|
|
||||||
|
|
||||||
SPU CORE0's DMA channel is 4 as per usual
|
|
||||||
SPU CORE1's DMA channel is 7
|
|
||||||
|
|
||||||
DMA channel 10 is SIF
|
|
||||||
|
|
||||||
Original INTR controller at 1F801000-1F80107F
|
|
||||||
|
|
||||||
All interrupt handling seems to be done using the old INTR, but
|
|
||||||
with some new bits defined:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reading from 1F801078 masks interrupts and returns 1 if they weren't
|
|
||||||
masked before. Writing 1 to 1F801078 re-enables interrupts.
|
|
||||||
Writing 0 doesn't. Maybe it was like that on the original PS1 too.
|
|
||||||
|
|
||||||
Six root counters:
|
|
||||||
|
|
||||||
RTC# address sources size prescale interrupt#
|
|
||||||
0 0x1F801100 sysclock,pixel 16 bit 1 only 4
|
|
||||||
1 0x1F801110 sysclock,hline 16 bit 1 only 5
|
|
||||||
2 0x1F801120 sysclock 16 bit 1,8 6
|
|
||||||
3 0x1F801480 sysclock,hline 32 bit 1 only 14
|
|
||||||
4 0x1F801490 sysclock 32 bit 1,8,16,256 15
|
|
||||||
5 0x1F8014A0 sysclock 32 bit 1,8,16,256 16
|
|
||||||
|
|
||||||
Count (0x0) and Compare (0x8) registers work as before, only with more bits
|
|
||||||
in the new counters.
|
|
||||||
|
|
||||||
Mode (0x4) works like this when written:
|
|
||||||
|
|
||||||
bits 0..2 gate
|
|
||||||
bit 3 reset on target
|
|
||||||
bit 4 target interrupt enable
|
|
||||||
bit 5 overflow interrupt enable
|
|
||||||
bit 6 master enable (?)
|
|
||||||
bit 7 ?
|
|
||||||
bit 8 clock select
|
|
||||||
bit 9 prescale (OLD)
|
|
||||||
bit 10..12 ?
|
|
||||||
bit 13..14 prescale (NEW)
|
|
||||||
bit 15 ? always set to 1
|
|
||||||
|
|
||||||
Gate:
|
|
||||||
TM_NO_GATE 000
|
|
||||||
TM_GATE_ON_Count 001
|
|
||||||
TM_GATE_ON_ClearStart 011
|
|
||||||
TM_GATE_ON_Clear_OFF_Start 101
|
|
||||||
TM_GATE_ON_Start 111
|
|
||||||
|
|
||||||
V-blank ----+ +----------------------------+ +------
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
+----+ +----+
|
|
||||||
TM_NO_GATE:
|
|
||||||
|
|
||||||
0================================>============
|
|
||||||
|
|
||||||
TM_GATE_ON_Count:
|
|
||||||
|
|
||||||
<---->0==========================><---->0=====
|
|
||||||
|
|
||||||
TM_GATE_ON_ClearStart:
|
|
||||||
|
|
||||||
0====>0================================>0=====
|
|
||||||
|
|
||||||
TM_GATE_ON_Clear_OFF_Start:
|
|
||||||
|
|
||||||
0====><-------------------------->0====><-----
|
|
||||||
|
|
||||||
TM_GATE_ON_Start:
|
|
||||||
|
|
||||||
<---->0==========================>============
|
|
||||||
|
|
||||||
reset on target: if set, counter resets to 0 when Compare value is reached
|
|
||||||
|
|
||||||
target interrupt enable: if set, interrupt when Compare value is reached
|
|
||||||
overflow interrupt enable: if set, interrupt when counter overflows
|
|
||||||
|
|
||||||
master enable: if this bit is clear, the timer should do nothing.
|
|
||||||
|
|
||||||
clock select: for counters 0, 1, and 3, setting this will select the alternate
|
|
||||||
counter (pixel or hline)
|
|
||||||
|
|
||||||
prescale (OLD): for counter 2 only. set this to prescale (divide) by 8.
|
|
||||||
|
|
||||||
prescale (NEW): for counters 4 and 5 only:
|
|
||||||
|
|
||||||
00 = prescale by 1
|
|
||||||
01 = prescale by 8
|
|
||||||
10 = prescale by 16
|
|
||||||
11 = prescale by 256
|
|
||||||
|
|
||||||
Writing 0x4 also clears the counter. (I think.)
|
|
||||||
|
|
||||||
When 0x4 is read, it becomes Status:
|
|
||||||
|
|
||||||
bit 0..10 ?
|
|
||||||
bit 11 compare value was reached
|
|
||||||
bit 12 count overflowed
|
|
||||||
bit 13..15 ?
|
|
||||||
|
|
||||||
Reading probably clears these bits.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1F8014B0 (word) - timer-related but otherwise unknown
|
|
||||||
1F8014C0 (word) - timer-related but otherwise unknown
|
|
||||||
|
|
||||||
|
|
||||||
don't currently know how the interrupts work for DMA ch7 yet
|
|
||||||
|
|
||||||
1F801060 (word) - address of some kind.
|
|
||||||
|
|
||||||
1F801450 (word) -
|
|
||||||
if bit 3 is SET, we're in PS1 mode.
|
|
||||||
if bit 3 is CLEAR, we're in PS2 IOP mode.
|
|
||||||
|
|
||||||
1F802070 (byte) - unknown. status byte of some kind? visible to EE?
|
|
||||||
|
|
||||||
1D000000-1D00007F (?) - SIF related
|
|
||||||
|
|
||||||
1D000020 (word) - read counter of some sort?
|
|
||||||
sceSifInit waits for bit 0x10000 of this to be set.
|
|
||||||
1D000030 (word) - read counter of some sort?
|
|
||||||
1D000040 (word) - read bits 0x20, 0x40 mean something
|
|
||||||
1D000060 (word) - used to detect whether the SIF interface exists
|
|
||||||
read must be 0x1D000060, or the top 20 bits must be zero
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// DirectX Audio SPU2 Driver for PCSX2
|
|
||||||
// audio.c by J.F. and Kanodin (hooper1@cox.net)
|
|
||||||
//
|
|
||||||
// Copyright 2003 J.F. and Kanodin, and distributed under the
|
|
||||||
// terms of the GNU General Public License, v2 or later.
|
|
||||||
// http://www.gnu.org/copyleft/gpl.html.
|
|
||||||
|
|
||||||
Included these just in case you need them J.F. - Kanodin
|
|
||||||
|
|
||||||
// Core Start Addresses
|
|
||||||
#define CORE0 0x1f900000
|
|
||||||
#define CORE1 0x1f900400
|
|
||||||
|
|
||||||
|
|
||||||
#define IOP_INT_VBLANK (1<<0)
|
|
||||||
#define IOP_INT_GM (1<<1)
|
|
||||||
#define IOP_INT_CDROM (1<<2)
|
|
||||||
#define IOP_INT_DMA (1<<3)
|
|
||||||
#define IOP_INT_RTC0 (1<<4)
|
|
||||||
#define IOP_INT_RTC1 (1<<5)
|
|
||||||
#define IOP_INT_RTC2 (1<<6)
|
|
||||||
#define IOP_INT_SIO0 (1<<7)
|
|
||||||
#define IOP_INT_SIO1 (1<<8)
|
|
||||||
#define IOP_INT_SPU (1<<9)
|
|
||||||
#define IOP_INT_PIO (1<<10)
|
|
||||||
#define IOP_INT_EVBLANK (1<<11)
|
|
||||||
#define IOP_INT_DVD (1<<12)
|
|
||||||
#define IOP_INT_PCMCIA (1<<13)
|
|
||||||
#define IOP_INT_RTC3 (1<<14)
|
|
||||||
#define IOP_INT_RTC4 (1<<15)
|
|
||||||
#define IOP_INT_RTC5 (1<<16)
|
|
||||||
#define IOP_INT_SIO2 (1<<17)
|
|
||||||
#define IOP_INT_HTR0 (1<<18)
|
|
||||||
#define IOP_INT_HTR1 (1<<19)
|
|
||||||
#define IOP_INT_HTR2 (1<<20)
|
|
||||||
#define IOP_INT_HTR3 (1<<21)
|
|
||||||
#define IOP_INT_USB (1<<22)
|
|
||||||
#define IOP_INT_EXTR (1<<23)
|
|
||||||
#define IOP_INT_FWRE (1<<24)
|
|
||||||
#define IOP_INT_FDMA (1<<25)
|
|
||||||
|
|
||||||
// CORE0 => +0x000, CORE1 => +0x400
|
|
||||||
|
|
||||||
// individual voice parameter regs
|
|
||||||
|
|
||||||
#define VP_VOLL(cr, vc) (0x400 * cr + (vc << 4)) // voice volume (left)
|
|
||||||
#define VP_VOLR(cr, vc) (0x400 * cr + 0x002 + (vc << 4)) // voice volume (right)
|
|
||||||
#define VP_PITCH(cr, vc) (0x400 * cr + 0x004 + (vc << 4)) // voice pitch
|
|
||||||
#define VP_ADSR1(cr, vc) (0x400 * cr + 0x006 + (vc << 4)) // voice envelope (AR, DR, SL)
|
|
||||||
#define VP_ADSR2(cr, vc) (0x400 * cr + 0x008 + (vc << 4)) // voice envelope (SR, RR)
|
|
||||||
#define VP_ENVX(cr, vc) (0x400 * cr + 0x00A + (vc << 4)) // voice envelope (current value)
|
|
||||||
#define VP_VOLXL(cr, vc) (0x400 * cr + 0x00C + (vc << 4)) // voice volume (current value left)
|
|
||||||
#define VP_VOLXR(cr, vc) (0x400 * cr + 0x00E + (vc << 4)) // voice volume (current value right)
|
|
||||||
|
|
||||||
#define VA_SSA(cr, vc) (0x400 * cr + 0x1C0 + (vc * 12)) // voice waveform data start address
|
|
||||||
#define VA_LSAX(cr, vc) (0x400 * cr + 0x1C4 + (vc * 12)) // voice waveform data loop address
|
|
||||||
#define VA_NAX(cr, vc) (0x400 * cr + 0x1C8 + (vc * 12)) // voice waveform data next address
|
|
||||||
|
|
||||||
// common settings
|
|
||||||
|
|
||||||
#define S_PMON(cr) (0x400 * cr + 0x180) // pitch modulation on
|
|
||||||
#define S_NON(cr) (0x400 * cr + 0x184) // noise generator on
|
|
||||||
#define S_VMIXL(cr) (0x400 * cr + 0x188) // voice output mixing (dry left)
|
|
||||||
#define S_VMIXEL(cr) (0x400 * cr + 0x18C) // voice output mixing (wet left)
|
|
||||||
#define S_VMIXR(cr) (0x400 * cr + 0x190) // voice output mixing (dry right)
|
|
||||||
#define S_VMIXER(cr) (0x400 * cr + 0x194) // voice output mixing (wet right)
|
|
||||||
#define P_MMIX(cr) (0x400 * cr + 0x198) // output type after voice mixing (See paragraph below)
|
|
||||||
#define P_ATTR(cr) (0x400 * cr + 0x19A) // core attributes (See paragraph below)
|
|
||||||
#define A_IRQA(cr) (0x400 * cr + 0x19C) // IRQ address
|
|
||||||
#define S_KON(cr) (0x400 * cr + 0x1A0) // key on (start voice sound generation)
|
|
||||||
#define S_KOFF(cr) (0x400 * cr + 0x1A4) // key off (end voice sound generation)
|
|
||||||
#define A_TSA(cr) (0x400 * cr + 0x1A8) // DMA transfer start address
|
|
||||||
#define P_DATA(cr) (0x400 * cr + 0x1AC) // DMA data register
|
|
||||||
#define P_CTRL(cr) (0x400 * cr + 0x1AE) // DMA control register
|
|
||||||
#define P_ADMAS(cr) (0x400 * cr + 0x1B0) // AutoDMA status
|
|
||||||
|
|
||||||
#define A_ESA(cr) (0x400 * cr + 0x2E0) // effects work area start address
|
|
||||||
|
|
||||||
#define FB_SRC_A(cr) (0x400 * cr + 0x2E4)
|
|
||||||
#define FB_SRC_B(cr) (0x400 * cr + 0x2E8)
|
|
||||||
#define IIR_DEST_A0(cr) (0x400 * cr + 0x2EC)
|
|
||||||
#define IIR_DEST_A1(cr) (0x400 * cr + 0x2F0)
|
|
||||||
#define ACC_SRC_A0(cr) (0x400 * cr + 0x2F4)
|
|
||||||
#define ACC_SRC_A1(cr) (0x400 * cr + 0x2F8)
|
|
||||||
#define ACC_SRC_B0(cr) (0x400 * cr + 0x2FC)
|
|
||||||
|
|
||||||
#define ACC_SRC_B1(cr) (0x400 * cr + 0x300)
|
|
||||||
#define IIR_SRC_A0(cr) (0x400 * cr + 0x304)
|
|
||||||
#define IIR_SRC_A1(cr) (0x400 * cr + 0x308)
|
|
||||||
#define IIR_DEST_B0(cr) (0x400 * cr + 0x30C)
|
|
||||||
#define IIR_DEST_B1(cr) (0x400 * cr + 0x310)
|
|
||||||
#define ACC_SRC_C0(cr) (0x400 * cr + 0x314)
|
|
||||||
#define ACC_SRC_C1(cr) (0x400 * cr + 0x318)
|
|
||||||
|
|
||||||
#define ACC_SRC_D0(cr) (0x400 * cr + 0x31C)
|
|
||||||
#define ACC_SRC_D1(cr) (0x400 * cr + 0x320)
|
|
||||||
#define IIR_SRC_B1(cr) (0x400 * cr + 0x324)
|
|
||||||
#define IIR_SRC_B0(cr) (0x400 * cr + 0x328)
|
|
||||||
#define MIX_DEST_A0(cr) (0x400 * cr + 0x32C)
|
|
||||||
#define MIX_DEST_A1(cr) (0x400 * cr + 0x330)
|
|
||||||
#define MIX_DEST_B0(cr) (0x400 * cr + 0x334)
|
|
||||||
#define MIX_DEST_B1(cr) (0x400 * cr + 0x338)
|
|
||||||
|
|
||||||
#define A_EEA(cr) (0x400 * cr + 0x33C) // effects work area end address
|
|
||||||
|
|
||||||
#define P_ENDX(cr) (0x400 * cr + 0x340) // voice loop end status
|
|
||||||
#define P_STAT(cr) (0x400 * cr + 0x344) // DMA status register
|
|
||||||
#define P_ENDS(cr) (0x400 * cr + 0x346) // ?
|
|
||||||
|
|
||||||
// CORE0 => +0x400, CORE1 => +0x428
|
|
||||||
|
|
||||||
#define P_MVOLL(cr) (0x28 * cr + 0x760) // master volume (left)
|
|
||||||
#define P_MVOLR(cr) (0x28 * cr + 0x762) // master volume (right)
|
|
||||||
#define P_EVOLL(cr) (0x28 * cr + 0x764) // effect return volume (left)
|
|
||||||
#define P_EVOLR(cr) (0x28 * cr + 0x766) // effect return volume (right)
|
|
||||||
#define P_AVOLL(cr) (0x28 * cr + 0x768) // core external input volume (left)
|
|
||||||
#define P_AVOLR(cr) (0x28 * cr + 0x76A) // core external input volume (right)
|
|
||||||
#define P_BVOLL(cr) (0x28 * cr + 0x76C) // sound data input volume (left)
|
|
||||||
#define P_BVOLR(cr) (0x28 * cr + 0x76E) // sound data input volume (right)
|
|
||||||
#define P_MVOLXL(cr) (0x28 * cr + 0x770) // current master volume (left)
|
|
||||||
#define P_MVOLXR(cr) (0x28 * cr + 0x772) // current master volume (right)
|
|
||||||
|
|
||||||
#define IIR_ALPHA(cr) (0x28 * cr + 0x774)
|
|
||||||
#define ACC_COEF_A(cr) (0x28 * cr + 0x776)
|
|
||||||
#define ACC_COEF_B(cr) (0x28 * cr + 0x778)
|
|
||||||
#define ACC_COEF_C(cr) (0x28 * cr + 0x77A)
|
|
||||||
#define ACC_COEF_D(cr) (0x28 * cr + 0x77C)
|
|
||||||
#define IIR_COEF(cr) (0x28 * cr + 0x77E)
|
|
||||||
#define FB_ALPHA(cr) (0x28 * cr + 0x780)
|
|
||||||
#define FB_X(cr) (0x28 * cr + 0x782)
|
|
||||||
#define IN_COEF_L(cr) (0x28 * cr + 0x784)
|
|
||||||
#define IN_COEF_R(cr) (0x28 * cr + 0x786)
|
|
||||||
|
|
||||||
// CORE1 only => +0x400
|
|
||||||
|
|
||||||
#define SPDIF_OUT 0x7C0 // SPDIF Out: OFF/'PCM'/Bitstream/Bypass
|
|
||||||
#define SPDIF_MODE 0x7C6
|
|
||||||
#define SPDIF_MEDIA 0x7C8 // SPDIF Media: 'CD'/DVD
|
|
||||||
#define SPDIF_COPY 0x7CA // SPDIF Copy Protection
|
|
||||||
|
|
||||||
// PS1 SPU CORE
|
|
||||||
|
|
||||||
// individual voice settings
|
|
||||||
|
|
||||||
#define SPU_VP_PITCH(vc) (0xC04 + (vc << 4)) // voice pitch
|
|
||||||
#define SPU_VA_SSA(vc) (0xC06 + (vc << 4)) // voice waveform data start address
|
|
||||||
#define SPU_VP_ADSR(vc) (0xC08 + (vc << 4)) // voice envelope
|
|
||||||
#define SPU_VA_SSA(vc) (0xC0E + (vc << 4)) // voice waveform data loop address
|
|
||||||
|
|
||||||
// common settings
|
|
||||||
|
|
||||||
#define SPU_P_MVOLL 0xD80 // master volume (left)
|
|
||||||
#define SPU_P_MVOLR 0xD82 // master volume (right)
|
|
||||||
#define SPU_P_RVOLL 0xD84 // effect return volume (left)
|
|
||||||
#define SPU_P_RVOLR 0xD86 // effect return volume (right)
|
|
||||||
#define SPU_S_KON1 0xD88 // key on
|
|
||||||
#define SPU_S_KON2 0xD8A //
|
|
||||||
#define SPU_S_KOFF1 0xD8C // key off
|
|
||||||
#define SPU_S_KOFF2 0xD8E //
|
|
||||||
#define SPU_S_PMON1 0xD90 // pitch modulation on
|
|
||||||
#define SPU_S_PMON2 0xD92 //
|
|
||||||
#define SPU_S_NON1 0xD94 // noise generator on
|
|
||||||
#define SPU_S_NON2 0xD96 //
|
|
||||||
#define SPU_S_RVBON1 0xD98 // effects on
|
|
||||||
#define SPU_S_RVBON2 0xD9A //
|
|
||||||
#define SPU_S_MUTE1 0xD9C // voice mute
|
|
||||||
#define SPU_S_MUTE2 0xD9E //
|
|
||||||
|
|
||||||
#define SPU_A_ESA 0xDA2 // effects work area start
|
|
||||||
#define SPU_A_IRQA 0xDA4 // IRQ address
|
|
||||||
#define SPU_A_TSA 0xDA6 // DMA transfer start address
|
|
||||||
#define SPU_P_DATA 0xDA8 // DMA data register
|
|
||||||
#define SPU_P_CTRL 0xDAA // DMA control register
|
|
||||||
#define SPU_P_STAT 0xDAE // DMA status register
|
|
||||||
|
|
||||||
#define SPU_P_CDL 0xDB0 // sound data input volume (left)
|
|
||||||
#define SPU_P_CDR 0xDB2 // sound data input volume (right)
|
|
||||||
#define SPU_P_EXTL 0xDB4 // external input volume (left)
|
|
||||||
#define SPU_P_EXTR 0xDB6 // external input volume (right)
|
|
||||||
|
|
||||||
#define SPU_P_REVERB 0xDC0 // effects control
|
|
||||||
|
|
||||||
|
|
||||||
// Individual voice parameter regs CORE 0
|
|
||||||
// Only
|
|
||||||
|
|
||||||
|
|
||||||
#define VP_VOLL(cr, vc) (0x400 * cr + (vc << 4)) // voice volume (left)
|
|
||||||
#define VP_VOLR(cr, vc) (0x400 * cr + 0x002 + (vc << 4)) // voice volume (right)
|
|
||||||
#define VP_PITCH(cr, vc) (0x400 * cr + 0x004 + (vc << 4)) // voice pitch
|
|
||||||
#define VP_ADSR1(cr, vc) (0x400 * cr + 0x006 + (vc << 4)) // voice envelope (AR, DR, SL)
|
|
||||||
#define VP_ADSR2(cr, vc) (0x400 * cr + 0x008 + (vc << 4)) // voice envelope (SR, RR)
|
|
||||||
#define VP_ENVX(cr, vc) (0x400 * cr + 0x00A + (vc << 4)) // voice envelope (current value)
|
|
||||||
#define VP_VOLXL(cr, vc) (0x400 * cr + 0x00C + (vc << 4)) // voice volume (current value left)
|
|
||||||
#define VP_VOLXR(cr, vc) (0x400 * cr + 0x00E + (vc << 4)) // voice volume (current value right)
|
|
||||||
|
|
||||||
#define VA_SSA(cr, vc) (0x400 * cr + 0x1C0 + (vc * 12)) // voice waveform data start address
|
|
||||||
#define VA_LSAX(cr, vc) (0x400 * cr + 0x1C4 + (vc * 12)) // voice waveform data loop address
|
|
||||||
#define VA_NAX(cr, vc) (0x400 * cr + 0x1C8 + (vc * 12)) // voice waveform data next address
|
|
||||||
|
|
||||||
|
|
||||||
// CORE 0 Common Settings
|
|
||||||
|
|
||||||
|
|
||||||
#define S_PMON(cr) (0x400 * cr + 0x180) // pitch modulation on
|
|
||||||
#define S_NON(cr) (0x400 * cr + 0x184) // noise generator on
|
|
||||||
#define S_VMIXL(cr) (0x400 * cr + 0x188) // voice output mixing (dry left)
|
|
||||||
#define S_VMIXEL(cr) (0x400 * cr + 0x18C) // voice output mixing (wet left)
|
|
||||||
#define S_VMIXR(cr) (0x400 * cr + 0x190) // voice output mixing (dry right)
|
|
||||||
#define S_VMIXER(cr) (0x400 * cr + 0x194) // voice output mixing (wet right)
|
|
||||||
#define P_MMIX(cr) (0x400 * cr + 0x198) // output type after voice mixing (See paragraph below)
|
|
||||||
#define P_ATTR(cr) (0x400 * cr + 0x19A) // core attributes (See paragraph below)
|
|
||||||
#define A_IRQA(cr) (0x400 * cr + 0x19C) // IRQ address
|
|
||||||
#define S_KON(cr) (0x400 * cr + 0x1A0) // key on (start voice sound generation)
|
|
||||||
#define S_KOFF(cr) (0x400 * cr + 0x1A4) // key off (end voice sound generation)
|
|
||||||
#define A_TSA(cr) (0x400 * cr + 0x1A8) // DMA transfer start address
|
|
||||||
#define P_DATA(cr) (0x400 * cr + 0x1AC) // DMA data register
|
|
||||||
#define P_CTRL(cr) (0x400 * cr + 0x1AE) // DMA control register
|
|
||||||
#define P_ADMAS(cr) (0x400 * cr + 0x1B0) // AutoDMA status
|
|
||||||
|
|
||||||
#define A_ESA(cr) (0x400 * cr + 0x2E0) // effects work area start address
|
|
||||||
|
|
||||||
|
|
||||||
// Core 0 Reverb Addresses
|
|
||||||
|
|
||||||
|
|
||||||
#define FB_SRC_A(cr) (0x400 * cr + 0x2E4)
|
|
||||||
#define FB_SRC_B(cr) (0x400 * cr + 0x2E8)
|
|
||||||
#define IIR_DEST_A0(cr) (0x400 * cr + 0x2EC)
|
|
||||||
#define IIR_DEST_A1(cr) (0x400 * cr + 0x2F0)
|
|
||||||
#define ACC_SRC_A0(cr) (0x400 * cr + 0x2F4)
|
|
||||||
#define ACC_SRC_A1(cr) (0x400 * cr + 0x2F8)
|
|
||||||
#define ACC_SRC_B0(cr) (0x400 * cr + 0x2FC)
|
|
||||||
|
|
||||||
#define ACC_SRC_B1(cr) (0x400 * cr + 0x300)
|
|
||||||
#define IIR_SRC_A0(cr) (0x400 * cr + 0x304)
|
|
||||||
#define IIR_SRC_A1(cr) (0x400 * cr + 0x308)
|
|
||||||
#define IIR_DEST_B0(cr) (0x400 * cr + 0x30C)
|
|
||||||
#define IIR_DEST_B1(cr) (0x400 * cr + 0x310)
|
|
||||||
#define ACC_SRC_C0(cr) (0x400 * cr + 0x314)
|
|
||||||
#define ACC_SRC_C1(cr) (0x400 * cr + 0x318)
|
|
||||||
|
|
||||||
#define ACC_SRC_D0(cr) (0x400 * cr + 0x31C)
|
|
||||||
#define ACC_SRC_D1(cr) (0x400 * cr + 0x320)
|
|
||||||
#define IIR_SRC_B1(cr) (0x400 * cr + 0x324)
|
|
||||||
#define IIR_SRC_B0(cr) (0x400 * cr + 0x328)
|
|
||||||
#define MIX_DEST_A0(cr) (0x400 * cr + 0x32C)
|
|
||||||
#define MIX_DEST_A1(cr) (0x400 * cr + 0x330)
|
|
||||||
#define MIX_DEST_B0(cr) (0x400 * cr + 0x334)
|
|
||||||
#define MIX_DEST_B1(cr) (0x400 * cr + 0x338)
|
|
||||||
|
|
||||||
#define A_EEA(cr) (0x400 * cr + 0x33C) // effects work area end address
|
|
||||||
|
|
||||||
#define P_ENDX(cr) (0x400 * cr + 0x340) // voice loop end status
|
|
||||||
#define P_STAT(cr) (0x400 * cr + 0x344) // DMA status register
|
|
||||||
#define P_ENDS(cr) (0x400 * cr + 0x346) // ?
|
|
||||||
|
|
||||||
|
|
||||||
// CORE 0 Specific
|
|
||||||
|
|
||||||
|
|
||||||
#define P_MVOLL(cr) (0x28 * cr + 0x760) // master volume (left)
|
|
||||||
#define P_MVOLR(cr) (0x28 * cr + 0x762) // master volume (right)
|
|
||||||
#define P_EVOLL(cr) (0x28 * cr + 0x764) // effect return volume (left)
|
|
||||||
#define P_EVOLR(cr) (0x28 * cr + 0x766) // effect return volume (right)
|
|
||||||
#define P_AVOLL(cr) (0x28 * cr + 0x768) // core external input volume (left)
|
|
||||||
#define P_AVOLR(cr) (0x28 * cr + 0x76A) // core external input volume (right)
|
|
||||||
#define P_BVOLL(cr) (0x28 * cr + 0x76C) // sound data input volume (left)
|
|
||||||
#define P_BVOLR(cr) (0x28 * cr + 0x76E) // sound data input volume (right)
|
|
||||||
#define P_MVOLXL(cr) (0x28 * cr + 0x770) // current master volume (left)
|
|
||||||
#define P_MVOLXR(cr) (0x28 * cr + 0x772) // current master volume (right)
|
|
||||||
|
|
||||||
|
|
||||||
// More CORE 0 Reverb
|
|
||||||
|
|
||||||
|
|
||||||
#define IIR_ALPHA(cr) (0x28 * cr + 0x774)
|
|
||||||
#define ACC_COEF_A(cr) (0x28 * cr + 0x776)
|
|
||||||
#define ACC_COEF_B(cr) (0x28 * cr + 0x778)
|
|
||||||
#define ACC_COEF_C(cr) (0x28 * cr + 0x77A)
|
|
||||||
#define ACC_COEF_D(cr) (0x28 * cr + 0x77C)
|
|
||||||
#define IIR_COEF(cr) (0x28 * cr + 0x77E)
|
|
||||||
#define FB_ALPHA(cr) (0x28 * cr + 0x780)
|
|
||||||
#define FB_X(cr) (0x28 * cr + 0x782)
|
|
||||||
#define IN_COEF_L(cr) (0x28 * cr + 0x784)
|
|
||||||
#define IN_COEF_R(cr) (0x28 * cr + 0x786)
|
|
||||||
|
|
||||||
|
|
||||||
// CORE 1 only
|
|
||||||
|
|
||||||
#define SPDIF_OUT 0x7C0 // SPDIF Out: OFF/'PCM'/Bitstream/Bypass
|
|
||||||
#define SPDIF_MODE 0x7C6
|
|
||||||
#define SPDIF_MEDIA 0x7C8 // SPDIF Media: 'CD'/DVD
|
|
||||||
#define SPDIF_COPY 0x7CA // SPDIF Copy Protection
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* PS1 SPU CORE
|
|
||||||
|
|
||||||
*** The below really isn't needed, only if you ***
|
|
||||||
*** want to add SPU support to the plugin ***
|
|
||||||
*** which I see no need to add at this time. ***
|
|
||||||
*** individual voice settings ***
|
|
||||||
|
|
||||||
#define SPU_VP_PITCH(vc) (0xC04 + (vc << 4)) // voice pitch
|
|
||||||
#define SPU_VA_SSA(vc) (0xC06 + (vc << 4)) // voice waveform data start address
|
|
||||||
#define SPU_VP_ADSR(vc) (0xC08 + (vc << 4)) // voice envelope
|
|
||||||
#define SPU_VA_SSA(vc) (0xC0E + (vc << 4)) // voice waveform data loop address
|
|
||||||
|
|
||||||
// common settings
|
|
||||||
|
|
||||||
#define SPU_P_MVOLL 0xD80 // master volume (left)
|
|
||||||
#define SPU_P_MVOLR 0xD82 // master volume (right)
|
|
||||||
#define SPU_P_RVOLL 0xD84 // effect return volume (left)
|
|
||||||
#define SPU_P_RVOLR 0xD86 // effect return volume (right)
|
|
||||||
#define SPU_S_KON1 0xD88 // key on
|
|
||||||
#define SPU_S_KON2 0xD8A //
|
|
||||||
#define SPU_S_KOFF1 0xD8C // key off
|
|
||||||
#define SPU_S_KOFF2 0xD8E //
|
|
||||||
#define SPU_S_PMON1 0xD90 // pitch modulation on
|
|
||||||
#define SPU_S_PMON2 0xD92 //
|
|
||||||
#define SPU_S_NON1 0xD94 // noise generator on
|
|
||||||
#define SPU_S_NON2 0xD96 //
|
|
||||||
#define SPU_S_RVBON1 0xD98 // effects on
|
|
||||||
#define SPU_S_RVBON2 0xD9A //
|
|
||||||
#define SPU_S_MUTE1 0xD9C // voice mute
|
|
||||||
#define SPU_S_MUTE2 0xD9E //
|
|
||||||
|
|
||||||
#define SPU_A_ESA 0xDA2 // effects work area start
|
|
||||||
#define SPU_A_IRQA 0xDA4 // IRQ address
|
|
||||||
#define SPU_A_TSA 0xDA6 // DMA transfer start address
|
|
||||||
#define SPU_P_DATA 0xDA8 // DMA data register
|
|
||||||
#define SPU_P_CTRL 0xDAA // DMA control register
|
|
||||||
#define SPU_P_STAT 0xDAE // DMA status register
|
|
||||||
|
|
||||||
#define SPU_P_CDL 0xDB0 // sound data input volume (left)
|
|
||||||
#define SPU_P_CDR 0xDB2 // sound data input volume (right)
|
|
||||||
#define SPU_P_EXTL 0xDB4 // external input volume (left)
|
|
||||||
#define SPU_P_EXTR 0xDB6 // external input volume (right)
|
|
||||||
|
|
||||||
#define SPU_P_REVERB 0xDC0 // effects control
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define H_SPUReverbAddr 0x0da2
|
|
||||||
#define H_SPUirqAddr 0x0da4
|
|
||||||
#define H_SPUaddr 0x0da6
|
|
||||||
#define H_SPUdata 0x0da8
|
|
||||||
#define H_SPUctrl 0x0daa
|
|
||||||
#define H_SPUstat 0x0dae
|
|
||||||
#define H_SPUmvolL 0x0d80
|
|
||||||
#define H_SPUmvolR 0x0d82
|
|
||||||
#define H_SPUrvolL 0x0d84
|
|
||||||
#define H_SPUrvolR 0x0d86
|
|
||||||
#define H_SPUon1 0x0d88
|
|
||||||
#define H_SPUon2 0x0d8a
|
|
||||||
#define H_SPUoff1 0x0d8c
|
|
||||||
#define H_SPUoff2 0x0d8e
|
|
||||||
#define H_FMod1 0x0d90
|
|
||||||
#define H_FMod2 0x0d92
|
|
||||||
#define H_Noise1 0x0d94
|
|
||||||
#define H_Noise2 0x0d96
|
|
||||||
#define H_RVBon1 0x0d98
|
|
||||||
#define H_RVBon2 0x0d9a
|
|
||||||
#define H_SPUMute1 0x0d9c
|
|
||||||
#define H_SPUMute2 0x0d9e
|
|
||||||
#define H_CDLeft 0x0db0
|
|
||||||
#define H_CDRight 0x0db2
|
|
||||||
#define H_ExtLeft 0x0db4
|
|
||||||
#define H_ExtRight 0x0db6
|
|
||||||
#define H_Reverb 0x0dc0
|
|
||||||
#define H_SPUPitch0 0x0c04
|
|
||||||
#define H_SPUPitch1 0x0c14
|
|
||||||
#define H_SPUPitch2 0x0c24
|
|
||||||
#define H_SPUPitch3 0x0c34
|
|
||||||
#define H_SPUPitch4 0x0c44
|
|
||||||
#define H_SPUPitch5 0x0c54
|
|
||||||
#define H_SPUPitch6 0x0c64
|
|
||||||
#define H_SPUPitch7 0x0c74
|
|
||||||
#define H_SPUPitch8 0x0c84
|
|
||||||
#define H_SPUPitch9 0x0c94
|
|
||||||
#define H_SPUPitch10 0x0ca4
|
|
||||||
#define H_SPUPitch11 0x0cb4
|
|
||||||
#define H_SPUPitch12 0x0cc4
|
|
||||||
#define H_SPUPitch13 0x0cd4
|
|
||||||
#define H_SPUPitch14 0x0ce4
|
|
||||||
#define H_SPUPitch15 0x0cf4
|
|
||||||
#define H_SPUPitch16 0x0d04
|
|
||||||
#define H_SPUPitch17 0x0d14
|
|
||||||
#define H_SPUPitch18 0x0d24
|
|
||||||
#define H_SPUPitch19 0x0d34
|
|
||||||
#define H_SPUPitch20 0x0d44
|
|
||||||
#define H_SPUPitch21 0x0d54
|
|
||||||
#define H_SPUPitch22 0x0d64
|
|
||||||
#define H_SPUPitch23 0x0d74
|
|
||||||
|
|
||||||
#define H_SPUStartAdr0 0x0c06
|
|
||||||
#define H_SPUStartAdr1 0x0c16
|
|
||||||
#define H_SPUStartAdr2 0x0c26
|
|
||||||
#define H_SPUStartAdr3 0x0c36
|
|
||||||
#define H_SPUStartAdr4 0x0c46
|
|
||||||
#define H_SPUStartAdr5 0x0c56
|
|
||||||
#define H_SPUStartAdr6 0x0c66
|
|
||||||
#define H_SPUStartAdr7 0x0c76
|
|
||||||
#define H_SPUStartAdr8 0x0c86
|
|
||||||
#define H_SPUStartAdr9 0x0c96
|
|
||||||
#define H_SPUStartAdr10 0x0ca6
|
|
||||||
#define H_SPUStartAdr11 0x0cb6
|
|
||||||
#define H_SPUStartAdr12 0x0cc6
|
|
||||||
#define H_SPUStartAdr13 0x0cd6
|
|
||||||
#define H_SPUStartAdr14 0x0ce6
|
|
||||||
#define H_SPUStartAdr15 0x0cf6
|
|
||||||
#define H_SPUStartAdr16 0x0d06
|
|
||||||
#define H_SPUStartAdr17 0x0d16
|
|
||||||
#define H_SPUStartAdr18 0x0d26
|
|
||||||
#define H_SPUStartAdr19 0x0d36
|
|
||||||
#define H_SPUStartAdr20 0x0d46
|
|
||||||
#define H_SPUStartAdr21 0x0d56
|
|
||||||
#define H_SPUStartAdr22 0x0d66
|
|
||||||
#define H_SPUStartAdr23 0x0d76
|
|
||||||
|
|
||||||
#define H_SPULoopAdr0 0x0c0e
|
|
||||||
#define H_SPULoopAdr1 0x0c1e
|
|
||||||
#define H_SPULoopAdr2 0x0c2e
|
|
||||||
#define H_SPULoopAdr3 0x0c3e
|
|
||||||
#define H_SPULoopAdr4 0x0c4e
|
|
||||||
#define H_SPULoopAdr5 0x0c5e
|
|
||||||
#define H_SPULoopAdr6 0x0c6e
|
|
||||||
#define H_SPULoopAdr7 0x0c7e
|
|
||||||
#define H_SPULoopAdr8 0x0c8e
|
|
||||||
#define H_SPULoopAdr9 0x0c9e
|
|
||||||
#define H_SPULoopAdr10 0x0cae
|
|
||||||
#define H_SPULoopAdr11 0x0cbe
|
|
||||||
#define H_SPULoopAdr12 0x0cce
|
|
||||||
#define H_SPULoopAdr13 0x0cde
|
|
||||||
#define H_SPULoopAdr14 0x0cee
|
|
||||||
#define H_SPULoopAdr15 0x0cfe
|
|
||||||
#define H_SPULoopAdr16 0x0d0e
|
|
||||||
#define H_SPULoopAdr17 0x0d1e
|
|
||||||
#define H_SPULoopAdr18 0x0d2e
|
|
||||||
#define H_SPULoopAdr19 0x0d3e
|
|
||||||
#define H_SPULoopAdr20 0x0d4e
|
|
||||||
#define H_SPULoopAdr21 0x0d5e
|
|
||||||
#define H_SPULoopAdr22 0x0d6e
|
|
||||||
#define H_SPULoopAdr23 0x0d7e
|
|
||||||
|
|
||||||
#define H_SPU_ADSRLevel0 0x0c08
|
|
||||||
#define H_SPU_ADSRLevel1 0x0c18
|
|
||||||
#define H_SPU_ADSRLevel2 0x0c28
|
|
||||||
#define H_SPU_ADSRLevel3 0x0c38
|
|
||||||
#define H_SPU_ADSRLevel4 0x0c48
|
|
||||||
#define H_SPU_ADSRLevel5 0x0c58
|
|
||||||
#define H_SPU_ADSRLevel6 0x0c68
|
|
||||||
#define H_SPU_ADSRLevel7 0x0c78
|
|
||||||
#define H_SPU_ADSRLevel8 0x0c88
|
|
||||||
#define H_SPU_ADSRLevel9 0x0c98
|
|
||||||
#define H_SPU_ADSRLevel10 0x0ca8
|
|
||||||
#define H_SPU_ADSRLevel11 0x0cb8
|
|
||||||
#define H_SPU_ADSRLevel12 0x0cc8
|
|
||||||
#define H_SPU_ADSRLevel13 0x0cd8
|
|
||||||
#define H_SPU_ADSRLevel14 0x0ce8
|
|
||||||
#define H_SPU_ADSRLevel15 0x0cf8
|
|
||||||
#define H_SPU_ADSRLevel16 0x0d08
|
|
||||||
#define H_SPU_ADSRLevel17 0x0d18
|
|
||||||
#define H_SPU_ADSRLevel18 0x0d28
|
|
||||||
#define H_SPU_ADSRLevel19 0x0d38
|
|
||||||
#define H_SPU_ADSRLevel20 0x0d48
|
|
||||||
#define H_SPU_ADSRLevel21 0x0d58
|
|
||||||
#define H_SPU_ADSRLevel22 0x0d68
|
|
||||||
#define H_SPU_ADSRLevel23 0x0d78
|
|
||||||
*/
|
|
|
@ -1,43 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
regs.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
|
|
||||||
void SoundOn(int start,int end,unsigned short val);
|
|
||||||
void SoundOff(int start,int end,unsigned short val);
|
|
||||||
void VolumeOn(int start,int end,unsigned short val,int iRight);
|
|
||||||
void FModOn(int start,int end,unsigned short val);
|
|
||||||
void NoiseOn(int start,int end,unsigned short val);
|
|
||||||
void SetVolumeL(unsigned char ch,short vol);
|
|
||||||
void SetVolumeR(unsigned char ch,short vol);
|
|
||||||
void SetPitch(int ch,unsigned short val);
|
|
||||||
void ReverbOn(int start,int end,unsigned short val,int iRight);
|
|
||||||
void SetReverbAddr(int core);
|
|
||||||
|
|
||||||
EXPORT_GCC void CALLBACK SPU2write(unsigned long reg, unsigned short val);
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
//
|
|
||||||
// SPU2PEOPSSOUND.RC2 - resources Microsoft Visual C++ does not edit directly
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#error this file is not editable by Microsoft Visual C++
|
|
||||||
#endif //APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Add manually edited resources here...
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
|
@ -1,161 +0,0 @@
|
||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by spu2PeopsSound.rc
|
|
||||||
//
|
|
||||||
#define IDC_SETS1 3
|
|
||||||
#define IDC_SETS2 4
|
|
||||||
#define IDOK2 5
|
|
||||||
#define IDD_DIALOG1 130
|
|
||||||
#define IDD_ABOUT 130
|
|
||||||
#define IDD_CFGDLG 131
|
|
||||||
#define IDD_DEBUG 135
|
|
||||||
#define IDB_BITMAP1 136
|
|
||||||
#define IDB_BITMAP2 137
|
|
||||||
#define IDB_BITMAP3 138
|
|
||||||
#define IDB_BITMAP4 139
|
|
||||||
#define IDB_BITMAP5 140
|
|
||||||
#define IDD_RECORD 141
|
|
||||||
#define IDC_XAVOLUME 1004
|
|
||||||
#define IDC_ENABXA 1005
|
|
||||||
#define IDC_XAPITCH 1006
|
|
||||||
#define IDC_XABLOCK 1007
|
|
||||||
#define IDC_USETIMER 1007
|
|
||||||
#define IDC_TIMER 1007
|
|
||||||
#define IDC_CMIXRATE 1008
|
|
||||||
#define IDC_USEIRQ 1008
|
|
||||||
#define IDC_USEREVERB 1008
|
|
||||||
#define IDC_CMODE 1009
|
|
||||||
#define IDC_VOLUME 1009
|
|
||||||
#define IDC_CFILTER 1010
|
|
||||||
#define IDC_IRQWAIT 1010
|
|
||||||
#define IDC_CQUALITY 1011
|
|
||||||
#define IDC_DEBUGMODE 1011
|
|
||||||
#define IDC_CDSOUND 1012
|
|
||||||
#define IDC_INTERPOL 1012
|
|
||||||
#define IDC_PLAYALWAYS 1013
|
|
||||||
#define IDC_RECORDMODE 1013
|
|
||||||
#define IDC_IGNOREPITCH 1014
|
|
||||||
#define IDC_DISSTEREO 1014
|
|
||||||
#define IDC_AMPLIF 1015
|
|
||||||
#define IDC_VENVELOPE 1016
|
|
||||||
#define IDC_VOL1 1016
|
|
||||||
#define IDC_REVERB 1017
|
|
||||||
#define IDC_VOL2 1017
|
|
||||||
#define IDC_VOL3 1018
|
|
||||||
#define IDC_VOL4 1019
|
|
||||||
#define IDC_SAREA 1022
|
|
||||||
#define IDC_ADSR 1023
|
|
||||||
#define IDC_MUTE1 1047
|
|
||||||
#define IDC_MUTE2 1048
|
|
||||||
#define IDC_MUTE3 1049
|
|
||||||
#define IDC_MUTE4 1050
|
|
||||||
#define IDC_MUTE5 1051
|
|
||||||
#define IDC_MUTE6 1052
|
|
||||||
#define IDC_MUTE7 1053
|
|
||||||
#define IDC_MUTE8 1054
|
|
||||||
#define IDC_MUTE9 1055
|
|
||||||
#define IDC_MUTE10 1056
|
|
||||||
#define IDC_MUTE11 1057
|
|
||||||
#define IDC_MUTE12 1058
|
|
||||||
#define IDC_MUTE13 1059
|
|
||||||
#define IDC_MUTE14 1060
|
|
||||||
#define IDC_MUTE15 1061
|
|
||||||
#define IDC_MUTE16 1062
|
|
||||||
#define IDC_MUTE17 1063
|
|
||||||
#define IDC_MUTE18 1064
|
|
||||||
#define IDC_MUTE19 1065
|
|
||||||
#define IDC_MUTE20 1066
|
|
||||||
#define IDC_MUTE21 1067
|
|
||||||
#define IDC_MUTE22 1068
|
|
||||||
#define IDC_MUTE23 1069
|
|
||||||
#define IDC_MUTE24 1070
|
|
||||||
#define IDC_CHAN1 1071
|
|
||||||
#define IDC_CHAN2 1072
|
|
||||||
#define IDC_CHAN3 1073
|
|
||||||
#define IDC_CHAN4 1074
|
|
||||||
#define IDC_CHAN5 1075
|
|
||||||
#define IDC_CHAN6 1076
|
|
||||||
#define IDC_CHAN7 1077
|
|
||||||
#define IDC_CHAN8 1078
|
|
||||||
#define IDC_CHAN9 1079
|
|
||||||
#define IDC_CHAN10 1080
|
|
||||||
#define IDC_CHAN11 1081
|
|
||||||
#define IDC_CHAN12 1082
|
|
||||||
#define IDC_CHAN13 1083
|
|
||||||
#define IDC_CHAN14 1084
|
|
||||||
#define IDC_CHAN15 1085
|
|
||||||
#define IDC_CHAN16 1086
|
|
||||||
#define IDC_CHAN17 1087
|
|
||||||
#define IDC_CHAN18 1088
|
|
||||||
#define IDC_CHAN19 1089
|
|
||||||
#define IDC_CHAN20 1090
|
|
||||||
#define IDC_CHAN21 1091
|
|
||||||
#define IDC_CHAN22 1092
|
|
||||||
#define IDC_CHAN23 1093
|
|
||||||
#define IDC_CHAN24 1094
|
|
||||||
#define IDC_SADSR1 1096
|
|
||||||
#define IDC_SADSR2 1097
|
|
||||||
#define IDC_SADSR3 1098
|
|
||||||
#define IDC_SADSR4 1099
|
|
||||||
#define IDC_SADSR5 1100
|
|
||||||
#define IDC_SADSR6 1101
|
|
||||||
#define IDC_CHANNUM 1102
|
|
||||||
#define IDC_MUTEOFF 1103
|
|
||||||
#define IDC_MUTEON 1104
|
|
||||||
#define IDC_SADSR7 1105
|
|
||||||
#define IDC_CI1 1106
|
|
||||||
#define IDC_CI2 1107
|
|
||||||
#define IDC_CI3 1108
|
|
||||||
#define IDC_CI4 1109
|
|
||||||
#define IDC_CI5 1110
|
|
||||||
#define IDC_CI6 1111
|
|
||||||
#define IDC_CI7 1112
|
|
||||||
#define IDC_CI8 1113
|
|
||||||
#define IDC_CI9 1114
|
|
||||||
#define IDC_CI10 1115
|
|
||||||
#define IDC_CI11 1116
|
|
||||||
#define IDC_CI12 1117
|
|
||||||
#define IDC_CI13 1118
|
|
||||||
#define IDC_CI14 1119
|
|
||||||
#define IDC_CI15 1120
|
|
||||||
#define IDC_CI16 1121
|
|
||||||
#define IDC_STA1 1122
|
|
||||||
#define IDC_SADSR8 1123
|
|
||||||
#define IDC_STA2 1124
|
|
||||||
#define IDC_STA3 1125
|
|
||||||
#define IDC_STA4 1126
|
|
||||||
#define IDC_XA1 1127
|
|
||||||
#define IDC_XA2 1128
|
|
||||||
#define IDC_XA3 1129
|
|
||||||
#define IDC_XA4 1130
|
|
||||||
#define IDC_CI17 1131
|
|
||||||
#define IDC_CI18 1132
|
|
||||||
#define IDC_XA 1133
|
|
||||||
#define IDC_WAVFILE 1134
|
|
||||||
#define IDC_CI19 1134
|
|
||||||
#define IDC_XA5 1135
|
|
||||||
#define IDC_RECORD 1135
|
|
||||||
#define IDC_XA6 1136
|
|
||||||
#define IDC_CORE1 1137
|
|
||||||
#define IDC_CORE2 1138
|
|
||||||
#define IDC_REGWRITE 1139
|
|
||||||
#define IDC_REGREAD 1140
|
|
||||||
#define IDC_CLEAR 1141
|
|
||||||
#define IDC_LOG 1142
|
|
||||||
#define IDC_NOLOG 1143
|
|
||||||
#define IDC_REGEDIT 1144
|
|
||||||
#define IDC_VALEDIT 1145
|
|
||||||
#define IDC_COPY 1146
|
|
||||||
#define IDC_ASYNC 1147
|
|
||||||
#define IDC_SPU2IRQ 1148
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 142
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1149
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,420 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
reverb.c - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed to SPU2 functionality
|
|
||||||
//
|
|
||||||
// 2003/01/19 - Pete
|
|
||||||
// - added Neill's reverb (see at the end of file)
|
|
||||||
//
|
|
||||||
// 2002/12/26 - Pete
|
|
||||||
// - adjusted reverb handling
|
|
||||||
//
|
|
||||||
// 2002/08/14 - Pete
|
|
||||||
// - added extra reverb
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#define _IN_REVERB
|
|
||||||
|
|
||||||
// will be included from spu.c
|
|
||||||
#ifdef _IN_SPU
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// globals
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// REVERB info and timing vars...
|
|
||||||
|
|
||||||
int * sRVBPlay[2];
|
|
||||||
int * sRVBEnd[2];
|
|
||||||
int * sRVBStart[2];
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// START REVERB
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE void StartREVERB(int ch)
|
|
||||||
{
|
|
||||||
int core=ch/24;
|
|
||||||
|
|
||||||
if((s_chan[ch].bReverbL || s_chan[ch].bReverbR) && (spuCtrl2[core]&0x80)) // reverb possible?
|
|
||||||
{
|
|
||||||
if(iUseReverb==1) s_chan[ch].bRVBActive=1;
|
|
||||||
}
|
|
||||||
else s_chan[ch].bRVBActive=0; // else -> no reverb
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// HELPER FOR NEILL'S REVERB: re-inits our reverb mixing buf
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE void InitREVERB(void)
|
|
||||||
{
|
|
||||||
if(iUseReverb==1)
|
|
||||||
{
|
|
||||||
memset(sRVBStart[0],0,NSSIZE*2*4);
|
|
||||||
memset(sRVBStart[1],0,NSSIZE*2*4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// STORE REVERB
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE void StoreREVERB(int ch,int ns)
|
|
||||||
{
|
|
||||||
int core=ch/24;
|
|
||||||
|
|
||||||
if(iUseReverb==0) return;
|
|
||||||
else
|
|
||||||
if(iUseReverb==1) // -------------------------------- // Neil's reverb
|
|
||||||
{
|
|
||||||
const int iRxl=(s_chan[ch].sval*s_chan[ch].iLeftVolume*s_chan[ch].bReverbL)/0x4000;
|
|
||||||
const int iRxr=(s_chan[ch].sval*s_chan[ch].iRightVolume*s_chan[ch].bReverbR)/0x4000;
|
|
||||||
|
|
||||||
ns<<=1;
|
|
||||||
|
|
||||||
*(sRVBStart[core]+ns) +=iRxl; // -> we mix all active reverb channels into an extra buffer
|
|
||||||
*(sRVBStart[core]+ns+1)+=iRxr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE int g_buffer(int iOff,int core) // get_buffer content helper: takes care about wraps
|
|
||||||
{
|
|
||||||
short * p=(short *)spuMem;
|
|
||||||
iOff=(iOff)+rvb[core].CurrAddr;
|
|
||||||
while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
|
|
||||||
while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
|
|
||||||
return (int)*(p+iOff);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE void s_buffer(int iOff,int iVal,int core) // set_buffer content helper: takes care about wraps and clipping
|
|
||||||
{
|
|
||||||
short * p=(short *)spuMem;
|
|
||||||
iOff=(iOff)+rvb[core].CurrAddr;
|
|
||||||
while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
|
|
||||||
while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
|
|
||||||
if(iVal<-33768L) iVal=-33768L;if(iVal>33768L) iVal=33768L;
|
|
||||||
*(p+iOff)=(short)iVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE void s_buffer1(int iOff,int iVal,int core) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
|
|
||||||
{
|
|
||||||
short * p=(short *)spuMem;
|
|
||||||
iOff=(iOff)+rvb[core].CurrAddr+1;
|
|
||||||
while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
|
|
||||||
while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
|
|
||||||
if(iVal<-33768L) iVal=-33768L;if(iVal>33768L) iVal=33768L;
|
|
||||||
*(p+iOff)=(short)iVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE int MixREVERBLeft(int ns,int core)
|
|
||||||
{
|
|
||||||
if(iUseReverb==1)
|
|
||||||
{
|
|
||||||
if(!rvb[core].StartAddr || !rvb[core].EndAddr ||
|
|
||||||
rvb[core].StartAddr>=rvb[core].EndAddr) // reverb is off
|
|
||||||
{
|
|
||||||
rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rvb[core].iCnt++;
|
|
||||||
|
|
||||||
if(rvb[core].iCnt&1) // we work on every second left value: downsample to 22 khz
|
|
||||||
{
|
|
||||||
if((spuCtrl2[core]&0x80)) // -> reverb on? oki
|
|
||||||
{
|
|
||||||
int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
|
|
||||||
|
|
||||||
const int INPUT_SAMPLE_L=*(sRVBStart[core]+(ns<<1));
|
|
||||||
const int INPUT_SAMPLE_R=*(sRVBStart[core]+(ns<<1)+1);
|
|
||||||
|
|
||||||
const int IIR_INPUT_A0 = (g_buffer(rvb[core].IIR_SRC_A0,core) * rvb[core].IIR_COEF)/33768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/33768L;
|
|
||||||
const int IIR_INPUT_A1 = (g_buffer(rvb[core].IIR_SRC_A1,core) * rvb[core].IIR_COEF)/33768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/33768L;
|
|
||||||
const int IIR_INPUT_B0 = (g_buffer(rvb[core].IIR_SRC_B0,core) * rvb[core].IIR_COEF)/33768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/33768L;
|
|
||||||
const int IIR_INPUT_B1 = (g_buffer(rvb[core].IIR_SRC_B1,core) * rvb[core].IIR_COEF)/33768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/33768L;
|
|
||||||
|
|
||||||
const int IIR_A0 = (IIR_INPUT_A0 * rvb[core].IIR_ALPHA)/33768L + (g_buffer(rvb[core].IIR_DEST_A0,core) * (33768L - rvb[core].IIR_ALPHA))/33768L;
|
|
||||||
const int IIR_A1 = (IIR_INPUT_A1 * rvb[core].IIR_ALPHA)/33768L + (g_buffer(rvb[core].IIR_DEST_A1,core) * (33768L - rvb[core].IIR_ALPHA))/33768L;
|
|
||||||
const int IIR_B0 = (IIR_INPUT_B0 * rvb[core].IIR_ALPHA)/33768L + (g_buffer(rvb[core].IIR_DEST_B0,core) * (33768L - rvb[core].IIR_ALPHA))/33768L;
|
|
||||||
const int IIR_B1 = (IIR_INPUT_B1 * rvb[core].IIR_ALPHA)/33768L + (g_buffer(rvb[core].IIR_DEST_B1,core) * (33768L - rvb[core].IIR_ALPHA))/33768L;
|
|
||||||
|
|
||||||
s_buffer1(rvb[core].IIR_DEST_A0, IIR_A0,core);
|
|
||||||
s_buffer1(rvb[core].IIR_DEST_A1, IIR_A1,core);
|
|
||||||
s_buffer1(rvb[core].IIR_DEST_B0, IIR_B0,core);
|
|
||||||
s_buffer1(rvb[core].IIR_DEST_B1, IIR_B1,core);
|
|
||||||
|
|
||||||
ACC0 = (g_buffer(rvb[core].ACC_SRC_A0,core) * rvb[core].ACC_COEF_A)/33768L +
|
|
||||||
(g_buffer(rvb[core].ACC_SRC_B0,core) * rvb[core].ACC_COEF_B)/33768L +
|
|
||||||
(g_buffer(rvb[core].ACC_SRC_C0,core) * rvb[core].ACC_COEF_C)/33768L +
|
|
||||||
(g_buffer(rvb[core].ACC_SRC_D0,core) * rvb[core].ACC_COEF_D)/33768L;
|
|
||||||
ACC1 = (g_buffer(rvb[core].ACC_SRC_A1,core) * rvb[core].ACC_COEF_A)/33768L +
|
|
||||||
(g_buffer(rvb[core].ACC_SRC_B1,core) * rvb[core].ACC_COEF_B)/33768L +
|
|
||||||
(g_buffer(rvb[core].ACC_SRC_C1,core) * rvb[core].ACC_COEF_C)/33768L +
|
|
||||||
(g_buffer(rvb[core].ACC_SRC_D1,core) * rvb[core].ACC_COEF_D)/33768L;
|
|
||||||
|
|
||||||
FB_A0 = g_buffer(rvb[core].MIX_DEST_A0 - rvb[core].FB_SRC_A,core);
|
|
||||||
FB_A1 = g_buffer(rvb[core].MIX_DEST_A1 - rvb[core].FB_SRC_A,core);
|
|
||||||
FB_B0 = g_buffer(rvb[core].MIX_DEST_B0 - rvb[core].FB_SRC_B,core);
|
|
||||||
FB_B1 = g_buffer(rvb[core].MIX_DEST_B1 - rvb[core].FB_SRC_B,core);
|
|
||||||
|
|
||||||
s_buffer(rvb[core].MIX_DEST_A0, ACC0 - (FB_A0 * rvb[core].FB_ALPHA)/33768L,core);
|
|
||||||
s_buffer(rvb[core].MIX_DEST_A1, ACC1 - (FB_A1 * rvb[core].FB_ALPHA)/33768L,core);
|
|
||||||
|
|
||||||
s_buffer(rvb[core].MIX_DEST_B0, (rvb[core].FB_ALPHA * ACC0)/33768L - (FB_A0 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/33768L - (FB_B0 * rvb[core].FB_X)/33768L,core);
|
|
||||||
s_buffer(rvb[core].MIX_DEST_B1, (rvb[core].FB_ALPHA * ACC1)/33768L - (FB_A1 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/33768L - (FB_B1 * rvb[core].FB_X)/33768L,core);
|
|
||||||
|
|
||||||
rvb[core].iLastRVBLeft = rvb[core].iRVBLeft;
|
|
||||||
rvb[core].iLastRVBRight = rvb[core].iRVBRight;
|
|
||||||
|
|
||||||
rvb[core].iRVBLeft = (g_buffer(rvb[core].MIX_DEST_A0,core)+g_buffer(rvb[core].MIX_DEST_B0,core))/3;
|
|
||||||
rvb[core].iRVBRight = (g_buffer(rvb[core].MIX_DEST_A1,core)+g_buffer(rvb[core].MIX_DEST_B1,core))/3;
|
|
||||||
|
|
||||||
rvb[core].iRVBLeft = (rvb[core].iRVBLeft * rvb[core].VolLeft) / 0x4000;
|
|
||||||
rvb[core].iRVBRight = (rvb[core].iRVBRight * rvb[core].VolRight) / 0x4000;
|
|
||||||
|
|
||||||
rvb[core].CurrAddr++;
|
|
||||||
if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
|
|
||||||
|
|
||||||
return rvb[core].iLastRVBLeft+(rvb[core].iRVBLeft-rvb[core].iLastRVBLeft)/2;
|
|
||||||
}
|
|
||||||
else // -> reverb off
|
|
||||||
{
|
|
||||||
rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rvb[core].CurrAddr++;
|
|
||||||
if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rvb[core].iLastRVBLeft;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
INLINE int MixREVERBRight(int core)
|
|
||||||
{
|
|
||||||
if(iUseReverb==1) // Neill's reverb:
|
|
||||||
{
|
|
||||||
int i=rvb[core].iLastRVBRight+(rvb[core].iRVBRight-rvb[core].iLastRVBRight)/2;
|
|
||||||
rvb[core].iLastRVBRight=rvb[core].iRVBRight;
|
|
||||||
return i; // -> just return the last right reverb val (little bit scaled by the previous right val)
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
PSX reverb hardware notes
|
|
||||||
by Neill Corlett
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Yadda yadda disclaimer yadda probably not perfect yadda well it's okay anyway
|
|
||||||
yadda yadda.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Basics
|
|
||||||
------
|
|
||||||
|
|
||||||
- The reverb buffer is 22khz 16-bit mono PCM.
|
|
||||||
- It starts at the reverb address given by 1DA2, extends to
|
|
||||||
the end of sound RAM, and wraps back to the 1DA2 address.
|
|
||||||
|
|
||||||
Setting the address at 1DA2 resets the current reverb work address.
|
|
||||||
|
|
||||||
This work address ALWAYS increments every 1/22050 sec., regardless of
|
|
||||||
whether reverb is enabled (bit 7 of 1DAA set).
|
|
||||||
|
|
||||||
And the contents of the reverb buffer ALWAYS play, scaled by the
|
|
||||||
"reverberation depth left/right" volumes (1D84/1D86).
|
|
||||||
(which, by the way, appear to be scaled so 3FFF=approx. 1.0, 4000=-1.0)
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Register names
|
|
||||||
--------------
|
|
||||||
|
|
||||||
These are probably not their real names.
|
|
||||||
These are probably not even correct names.
|
|
||||||
We will use them anyway, because we can.
|
|
||||||
|
|
||||||
1DC0: FB_SRC_A (offset)
|
|
||||||
1DC2: FB_SRC_B (offset)
|
|
||||||
1DC4: IIR_ALPHA (coef.)
|
|
||||||
1DC6: ACC_COEF_A (coef.)
|
|
||||||
1DC8: ACC_COEF_B (coef.)
|
|
||||||
1DCA: ACC_COEF_C (coef.)
|
|
||||||
1DCC: ACC_COEF_D (coef.)
|
|
||||||
1DCE: IIR_COEF (coef.)
|
|
||||||
1DD0: FB_ALPHA (coef.)
|
|
||||||
1DD2: FB_X (coef.)
|
|
||||||
1DD4: IIR_DEST_A0 (offset)
|
|
||||||
1DD6: IIR_DEST_A1 (offset)
|
|
||||||
1DD8: ACC_SRC_A0 (offset)
|
|
||||||
1DDA: ACC_SRC_A1 (offset)
|
|
||||||
1DDC: ACC_SRC_B0 (offset)
|
|
||||||
1DDE: ACC_SRC_B1 (offset)
|
|
||||||
1DE0: IIR_SRC_A0 (offset)
|
|
||||||
1DE2: IIR_SRC_A1 (offset)
|
|
||||||
1DE4: IIR_DEST_B0 (offset)
|
|
||||||
1DE6: IIR_DEST_B1 (offset)
|
|
||||||
1DE8: ACC_SRC_C0 (offset)
|
|
||||||
1DEA: ACC_SRC_C1 (offset)
|
|
||||||
1DEC: ACC_SRC_D0 (offset)
|
|
||||||
1DEE: ACC_SRC_D1 (offset)
|
|
||||||
1DF0: IIR_SRC_B1 (offset)
|
|
||||||
1DF2: IIR_SRC_B0 (offset)
|
|
||||||
1DF4: MIX_DEST_A0 (offset)
|
|
||||||
1DF6: MIX_DEST_A1 (offset)
|
|
||||||
1DF8: MIX_DEST_B0 (offset)
|
|
||||||
1DFA: MIX_DEST_B1 (offset)
|
|
||||||
1DFC: IN_COEF_L (coef.)
|
|
||||||
1DFE: IN_COEF_R (coef.)
|
|
||||||
|
|
||||||
The coefficients are signed fractional values.
|
|
||||||
-32768 would be -1.0
|
|
||||||
32768 would be 1.0 (if it were possible... the highest is of course 32767)
|
|
||||||
|
|
||||||
The offsets are (byte/8) offsets into the reverb buffer.
|
|
||||||
i.e. you multiply them by 8, you get byte offsets.
|
|
||||||
You can also think of them as (samples/4) offsets.
|
|
||||||
They appear to be signed. They can be negative.
|
|
||||||
None of the documented presets make them negative, though.
|
|
||||||
|
|
||||||
Yes, 1DF0 and 1DF2 appear to be backwards. Not a typo.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
What it does
|
|
||||||
------------
|
|
||||||
|
|
||||||
We take all reverb sources:
|
|
||||||
- regular channels that have the reverb bit on
|
|
||||||
- cd and external sources, if their reverb bits are on
|
|
||||||
and mix them into one stereo 44100hz signal.
|
|
||||||
|
|
||||||
Lowpass/downsample that to 22050hz. The PSX uses a proper bandlimiting
|
|
||||||
algorithm here, but I haven't figured out the hysterically exact specifics.
|
|
||||||
I use an 8-tap filter with these coefficients, which are nice but probably
|
|
||||||
not the real ones:
|
|
||||||
|
|
||||||
0.037828187894
|
|
||||||
0.157538631280
|
|
||||||
0.321159685278
|
|
||||||
0.449322115345
|
|
||||||
0.449322115345
|
|
||||||
0.321159685278
|
|
||||||
0.157538631280
|
|
||||||
0.037828187894
|
|
||||||
|
|
||||||
So we have two input samples (INPUT_SAMPLE_L, INPUT_SAMPLE_R) every 22050hz.
|
|
||||||
|
|
||||||
* IN MY EMULATION, I divide these by 2 to make it clip less.
|
|
||||||
(and of course the L/R output coefficients are adjusted to compensate)
|
|
||||||
The real thing appears to not do this.
|
|
||||||
|
|
||||||
At every 22050hz tick:
|
|
||||||
- If the reverb bit is enabled (bit 7 of 1DAA), execute the reverb
|
|
||||||
steady-state algorithm described below
|
|
||||||
- AFTERWARDS, retrieve the "wet out" L and R samples from the reverb buffer
|
|
||||||
(This part may not be exactly right and I guessed at the coefs. TODO: check later.)
|
|
||||||
L is: 0.333 * (buffer[MIX_DEST_A0] + buffer[MIX_DEST_B0])
|
|
||||||
R is: 0.333 * (buffer[MIX_DEST_A1] + buffer[MIX_DEST_B1])
|
|
||||||
- Advance the current buffer position by 1 sample
|
|
||||||
|
|
||||||
The wet out L and R are then upsampled to 44100hz and played at the
|
|
||||||
"reverberation depth left/right" (1D84/1D86) volume, independent of the main
|
|
||||||
volume.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Reverb steady-state
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The reverb steady-state algorithm is fairly clever, and of course by
|
|
||||||
"clever" I mean "batshit insane".
|
|
||||||
|
|
||||||
buffer[x] is relative to the current buffer position, not the beginning of
|
|
||||||
the buffer. Note that all buffer offsets must wrap around so they're
|
|
||||||
contained within the reverb work area.
|
|
||||||
|
|
||||||
Clipping is performed at the end... maybe also sooner, but definitely at
|
|
||||||
the end.
|
|
||||||
|
|
||||||
IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
|
|
||||||
IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
|
|
||||||
IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
|
|
||||||
IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
|
|
||||||
|
|
||||||
IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
|
|
||||||
IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
|
|
||||||
IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
|
|
||||||
IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
|
|
||||||
|
|
||||||
buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
|
|
||||||
buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
|
|
||||||
buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
|
|
||||||
buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
|
|
||||||
|
|
||||||
ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
|
|
||||||
buffer[ACC_SRC_B0] * ACC_COEF_B +
|
|
||||||
buffer[ACC_SRC_C0] * ACC_COEF_C +
|
|
||||||
buffer[ACC_SRC_D0] * ACC_COEF_D;
|
|
||||||
ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
|
|
||||||
buffer[ACC_SRC_B1] * ACC_COEF_B +
|
|
||||||
buffer[ACC_SRC_C1] * ACC_COEF_C +
|
|
||||||
buffer[ACC_SRC_D1] * ACC_COEF_D;
|
|
||||||
|
|
||||||
FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
|
|
||||||
FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
|
|
||||||
FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
|
|
||||||
FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
|
|
||||||
|
|
||||||
buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
|
|
||||||
buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
|
|
||||||
buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
|
|
||||||
buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
reverb.h - description
|
|
||||||
-------------------
|
|
||||||
begin : Wed May 15 2002
|
|
||||||
copyright : (C) 2002 by Pete Bernert
|
|
||||||
email : BlackDove@addcom.de
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. See also the license.txt file for *
|
|
||||||
* additional informations. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
//*************************************************************************//
|
|
||||||
// History of changes:
|
|
||||||
//
|
|
||||||
// 2004/04/04 - Pete
|
|
||||||
// - changed plugin to emulate PS2 spu
|
|
||||||
//
|
|
||||||
// 2002/05/15 - Pete
|
|
||||||
// - generic cleanup for the Peops release
|
|
||||||
//
|
|
||||||
//*************************************************************************//
|
|
||||||
|
|
||||||
|
|
||||||
INLINE void StartREVERB(int ch);
|
|
||||||
INLINE void StoreREVERB(int ch,int ns);
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue