<NME> CD.C
<BEF> #include "CD.H"

#include "CONTROL.H"
#include "SPECIFIC.H"

#include <assert.h>
#include <stdio.h>
#include <string.h>

//Number of XA files on disc (XA1-17.XA)
#define NUM_XA_FILES 17

#define XA_FILE_NAME "XA%d.XA"

#define CDS "CDS!" + __TIMESTAMP__ + " ."

unsigned short XATrackClip[] =//Probably used for XA audio start/end pos of each track
{
	0xFF00, 0xFF00, 0xFE80, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF80,
	0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00,
	0xFE80, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF80, 0xFF80,
	0xFE00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFE00, 0xFF80, 0xFF80,
	0xFF00, 0xFF00, 0xFF80, 0xFF80, 0xFF00, 0xFF00, 0xFF00, 0xFF80,
	0xFF80, 0xFE00, 0xFF80, 0xFF00, 0xFF80, 0xFF80, 0xFF80, 0xFF80,
	0xFF00, 0xFF00, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF00,
	0xFE00, 0xFF00, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF00, 0xFF80,
	0xFE00, 0xFD80, 0xFD80, 0xFE80, 0xFE80, 0xFE80, 0xFF00, 0xFF80,
	0xFA00, 0xFC00, 0xFC00, 0xFC00, 0xFD80, 0xFF00, 0xFE00, 0xFF80,
	0xFE00, 0xFE00, 0xFD80, 0xFE80, 0xFF00, 0xFF00, 0xFF00, 0xFF00,
	0xFA00, 0xFB00, 0xFC00, 0xFB80, 0xFC80, 0xFC80, 0xFF00, 0xFFC0,
int XAStartPos;
static int XATrackList[17][2];

void /*$ra*/ cbvsync()
{ // line 2, offset 0x5d884
	//int ret; // $a1
	//unsigned char io[8]; // stack offset -16
	{ // line 86, offset 0x5daec
		//int cnt; // $v0
	} // line 93, offset 0x5db20
} // line 120, offset 0x5dc10

void InitNewCDSystem()//5DDE8, 5E264(<)
{
volatile int XAEndPos;
volatile short XAVolume;
volatile short XAReqVolume;
volatile char XAFlag;
short XAMasterVolume;
short XATrack;
short XAReqTrack;
char XAWait;
static char XARepeat;
int XAStartPos;
static int XATrackList[17][2];

//Holds all game data file positions or offsets in GAMEWAD.OBJ.
struct GAMEWAD_header gwHeader;

//LBA for the GAMEWAD.OBJ file on disc, this is set by InitNewCDSystem(), CDPosToInt() (See CD.C)
int gwLba = 0;

//Start sector for the current gamewad file entry.
static int cdStartSector = 0;

//Current sector for the gamewad file entry, updated as data is read from disk.
int cdCurrentSector = 0;

void CDDA_SetVolume(int nVolume)//5D7FC(<), 5DC78(<)
{
	S_Warn("[CDDA_SetVolume] - Unimplemented!\n");
}

void XAReplay()//5D838(<), 5DCB4(<)
{
#if 0
	CdlLOC loc;

	CdIntToPos(XAStartPos, &loc);

	if (CdControl(CdlReadS, (unsigned char*)&loc, NULL) == 1)
	{
		XACurPos = XAStartPos;
	}
#endif

	return;
}

void cbvsync()//5D884(<), 5DD00(<)
{
	int ret;
	unsigned char io[8];
	int cnt;

	switch (XAFlag)
	{
	case 1:
	{
		if (XAVolume == 0)
		{
			XAFlag++;
		}
		//5DF9C
		break;
	}
	case 2:
	{
		cnt = XATrack = XAReqTrack;

		if (XAReqTrack < 0)
		{
			cnt = XAReqTrack + 7;
		}

		cnt &= ~3;//>>3<<3
		XAStartPos = XATrackList[cnt][0];
		io[0] = 1;
		XAEndPos = XATrackList[cnt][1] + XATrackClip[XAReqTrack];
		XAStartPos = 0;
		io[1] = XATrack & 7;
		XACurPos = XAStartPos;
		//CdControlF(CdlSetfilter, &io[0]);
		XAFlag++;

		break;
	}
	case 3:
	{
		//loc_5D980
		XAReplay();
		XAReqVolume = XAMasterVolume;
		XAFlag++;

		break;
	}
	case 4:
	{
		//loc_5D9AC
		if (XAVolume == XAMasterVolume)
		{
			XAFlag++;
			XAWait = 60;
		}

		break;
	}
	case 5:
	{
		//loc_5D9E0
		if (XAWait == 0)
		{
			XAFlag++;
		}

		XAWait--;

		break;
	}
	case 6:
	{
		//loc_5DA18
		if (0)//(((VSync(-1)) & 7) == 0)
		{
			//ret = CdSync(1, &io[0]);

			if (ret == 5)
			{
				XAReplay();
			}
			else if (ret == 2)
			{
				if (XACurPos > XAEndPos)
				{
					if (XARepeat)
					{
						XAReplay();
					}
					else
					{
						if (CurrentAtmosphere == 0)
						{
							//CdControlB(CdlPause, NULL, NULL);
							XAFlag = 7;
						}
						else
						{
							//5DAB8
							XAVolume = 0;
							XARepeat = 1;
							XAFlag = ret;
							XAReqTrack = CurrentAtmosphere;
							CDDA_SetVolume(0);
							IsAtmospherePlaying = 1;
						}
					}
				}
				else
				{
					//5DAEC
					/*if (CdLastCom() == 0x11)
					{
						cnt = CdPosToInt((CdlLOC*) &io[5]);
						if (cnt > 0)
						{
							XACurPos = cnt;
						}
					}

					CdControlF(CdlGetlocP, NULL);*/
				}
			}
		}
		break;
	}
	case 7:
		break;
	default:
		break;
	}

	if (XAVolume < XAReqVolume)
	{
		XAVolume += XAFadeRate;

		if (XAVolume > XAReqVolume)
		{
			XAVolume = XAReqVolume;
		}

		CDDA_SetVolume(XAVolume);
	}
	else if (XAReqVolume < XAVolume)
	{
		XAVolume -= XAFadeRate;

		if (XAReqVolume > XAVolume)
		{
			XAVolume = XAReqVolume;
		}

		CDDA_SetVolume(XAVolume);
	}

	//loc_5DC00
	return;
}

void S_CDPlay(short track, int mode)//5DC10(<), 5E08C(<) (F)
{
	unsigned char param[4];

	if (XATrack == -1)
	{
		param[0] = 200;
		//CdControlB(CdlSetmode, &param[0], NULL);
		//VSync(3);
		//CdControlB(CdlPause, NULL, NULL);
		DEL_ChangeCDMode(1);
	}

	if (XATrack != track && XAReqTrack != track)
	{
		XAReqTrack = track;
		XARepeat = mode;

		if (XAFlag != 0)
		{
			XAFlag = 1;
			XAReqVolume = 0;
		}
		else
		{
			XAFlag = 2;
		}
	}

	//loc_5DCBC
	return;
}

void S_CDStop()//5DCD0(<), 5E14C(<) (F) (*)
{
	XAFlag = 0;

	XAReqTrack = -1;
	XATrack = -1;

	DEL_ChangeCDMode(0);
	return;
}

void S_CDPause()//5DD14(<), 5E190(<) (F) (*)
{
	if (XATrack >= 0)
	{
		//CdControlF(CdlPause, 0);
	}

	return;
}

void S_CDRestart()//5DD40(<) (F) (*)
{
	if (XATrack >= 0 && XAFlag != 7)
	{
		//CdControlF(CdlReadS, 0);
	}

	return;
}

void S_StartSyncedAudio(int nTrack)//5DD78(<), 5E1F4(<) (F) (*)
{
	IsAtmospherePlaying = 0;

	S_CDPlay(nTrack, 0);

	while (XAFlag < 4) {}

	//VSync(29);

	return;
}

void CDDA_SetMasterVolume(int nVolume)//5DDC4(<), 5E240(<) (F)
{
	XAMasterVolume = nVolume;
	CDDA_SetVolume(nVolume);
}

void InitNewCDSystem()//5DDE8, 5E264(<) (F)
{
	char buf[10];
	int i = 0;
	long local_wadfile_header[512];

#if DISC_VERSION
	FILE* fileHandle = fopen(GAMEWAD_FILENAME, "rb");
	assert(fileHandle);
	fread(&local_wadfile_header, sizeof(struct GAMEWAD_header), 1, fileHandle);
	fclose(fileHandle);

	memcpy(&gwHeader, &local_wadfile_header, sizeof(struct GAMEWAD_header));//5F6AC

	//FIXME: CdPosToInt(); returns LBA for GAMEWAD.OBJ on disc.
	gwLba = 24;
#endif

	//loc_5E2E8
	for (i = 0; i < NUM_XA_FILES; i++)
	{
		sprintf(buf, XA_FILE_NAME, i + 1);
		FILE* fileHandle = fopen(buf, "rb");
		assert(fileHandle);
		fseek(fileHandle, 0, SEEK_END);
		XATrackList[i][0] = -1;//FIXME: This value is returned by CdPosToInt(); register is v0. It returns the LBA of the XA file on disc.
		XATrackList[i][1] = ((ftell(fileHandle) + ((1 << CD_SECTOR_SHIFT) - 1)) >> CD_SECTOR_SHIFT) + XATrackList[i][0];
		fclose(fileHandle);
	}

	XAFlag = 0;
	XAVolume = 0;
	XAReqTrack = -1;
	XATrack = -1;
}

void DEL_ChangeCDMode(int mode)//5DEB0(<), 5E650 (F) (*)
{
	unsigned char param[4];

	if (mode == 0)
	{
		if (current_cd_mode == 0)
		{
			return;
		}

		current_cd_mode = 0;

		//param[0] = CdlModeSpeed;
		//CdControlB(CdlSetmode, param, 0);
		//VSync(3);
	}
	else if (mode == 1)
	{
		//loc_5DEF8
		if (current_cd_mode == mode)
		{
			return;
		}

		current_cd_mode = mode;
	}
	else if (mode == 2)
	{
		//loc_5DF20
		if (current_cd_mode == mode)
		{
			return;
		}

		current_cd_mode = mode;

		//param[0] = CdlModeSpeed;
		//CdControlB(CdlSetmode, param, 0);
		//VSync(3);
	}

	//loc_5DF58
	return;
}

/*
* [FUNCTIONALITY] - DEL_CDFS_OpenFile.
* GAMEWAD_header is already in the memory at this point, we loaded it during InitNewCDSystem() (See CD.C)
* This method initialises the CD's read sector for a specific gamewad entry.
* File ID indices must match GAMEWAD.OBJ, see gw_files enum (GAMEWAD.H)
* Note: A File ID of "NONE" or 0 will initialise the reader position back to 0.
*
* [USAGE]
* @PARAM - [filenum] index into GAMEWAD_header.entries you wish to seek to.
* @RETURN - Filesize of the gamewad entry in bytes.
*/

int DEL_CDFS_OpenFile(int filenum /*$a0*/)//*, 5E3C0(<) (F)
{
	DEL_ChangeCDMode(0);
	cdCurrentSector = cdStartSector = (gwHeader.entries[filenum].fileOffset >> CD_SECTOR_SHIFT);
	return gwHeader.entries[filenum].fileSize;
}

/*
* [FUNCTIONALITY] - DEL_CDFS_Read
* It is assumed that prior to calling this you have initialised the cd's
* reader's position to the file entry you wish to read see (DEL_CDFS_OpenFile)
* This method reads data from disc at it's last sectior/read position.
*
* [USAGE]
* @PARAM - [size] the number of bytes you wish to read [addr] the memory location the data is read to.
*/

int DEL_CDFS_Read(char* addr, int size)//*, 5E414(<) (F) (*)
{
	int i;
	int numSectorsToRead;
	int remainingDataToRead;

	FILE* fileHandle = NULL;

	fileHandle = fopen(GAMEWAD_FILENAME, "rb");
	assert(fileHandle);
	fseek(fileHandle, cdCurrentSector << CD_SECTOR_SHIFT, SEEK_SET);

	remainingDataToRead = size & ((1 << CD_SECTOR_SHIFT) - 1);
	numSectorsToRead = size >> CD_SECTOR_SHIFT;

	if (numSectorsToRead != 0)
	{
		for (i = 0; i < numSectorsToRead; i++)
		{
			addr += fread(addr, 1, CD_SECTOR_SIZE, fileHandle);
		}

		cdCurrentSector += numSectorsToRead;
	}

	//Another chunk that is not multiple of 2048 bytes exists, read it
	if (remainingDataToRead != 0)//%
	{
		addr += fread(addr, 1, remainingDataToRead, fileHandle);
		cdCurrentSector++;
	}

	fclose(fileHandle);

	return 0;
}

/*
* [FUNCTIONALITY] - DEL_CDFS_Seek
* Seeks from the cd reader's current position.
* Note: Negative numbers will allow backwards traversal.
* [USAGE]
* @PARAM - [offset] the number of bytes you wish to seek (not in sectors).
*/

int DEL_CDFS_Seek(int offset /*$a0*/)//*, 5E54C(<) (F) (*)
{
	cdCurrentSector = cdStartSector + (offset >> CD_SECTOR_SHIFT);
	return 0;
}

/*
* [FUNCTIONALITY] - FRIG_CD_POS_TO_CUR
* Updates the cd reader's start sector to current reader position.
*/

void FRIG_CD_POS_TO_CUR()//*, 5E564(<) (F) (*)
{
	cdStartSector = cdCurrentSector;
}
<MSG> Finish VSyncFunc();

<DFF> @@ -31,14 +31,10 @@ static char XARepeat;
 int XAStartPos;
 static int XATrackList[17][2];
 
-void /*$ra*/ cbvsync()
-{ // line 2, offset 0x5d884
-	//int ret; // $a1
-	//unsigned char io[8]; // stack offset -16
-	{ // line 86, offset 0x5daec
-		//int cnt; // $v0
-	} // line 93, offset 0x5db20
-} // line 120, offset 0x5dc10
+void cbvsync()
+{
+	S_Warn("[cbvsync] - Unimplemented!\n");
+}
 
 void InitNewCDSystem()//5DDE8, 5E264(<)
 {

{'commit': 'diff --git a/SPEC_PSXPC/CD.C b/SPEC_PSXPC/CD.C\nindex 3b7df431..3fb5c63a 100644\n--- a/SPEC_PSXPC/CD.C\n+++ b/SPEC_PSXPC/CD.C\n@@ -31,14 +31,10 @@ static char XARepeat;\n int XAStartPos;\n static int XATrackList[17][2];\n \n-void /*$ra*/ cbvsync()\n-{ // line 2, offset 0x5d884\n-\t//int ret; // $a1\n-\t//unsigned char io[8]; // stack offset -16\n-\t{ // line 86, offset 0x5daec\n-\t\t//int cnt; // $v0\n-\t} // line 93, offset 0x5db20\n-} // line 120, offset 0x5dc10\n+void cbvsync()\n+{\n+\tS_Warn("[cbvsync] - Unimplemented!\\n");\n+}\n \n void InitNewCDSystem()//5DDE8, 5E264(<)\n {\ndiff --git a/SPEC_PSXPC/PSXMAIN.C b/SPEC_PSXPC/PSXMAIN.C\nindex 93a85e39..574c9383 100644\n--- a/SPEC_PSXPC/PSXMAIN.C\n+++ b/SPEC_PSXPC/PSXMAIN.C\n@@ -2,7 +2,7 @@\n \n #include "CD.H"\n #include "GAMEFLOW.H"\n-//#include "GPU.H"\n+#include "GPU.H"\n #include "LOAD_LEV.H"\n #include "MALLOC.H"\n #include "PROFILE.H"\n@@ -14,23 +14,20 @@\n \n unsigned long dword_9A884 = 0;\n \n-void VSyncFunc()\n+void VSyncFunc()//10000(<), 10000(<) (F)\n {\n-#if 0\n \tcbvsync();\n \n-\tif (LoadingBarEnabled == 0)\n+\tif (LoadingBarEnabled != 0)\n \t{\n-\t\t//LOAD_VSyncHandler();\n-\n-\t\tGnFrameCounter++;\n-\t\tGnLastFrameCount++;\n-\t}\n-\telse\n-\t{\n-\t\t//LOAD_VSyncHandler();\n+\t\tLOAD_VSyncHandler();\n \t}\n-#endif\n+\n+\t//loc_1002C\n+\tGnFrameCounter++;\n+\tGnLastFrameCount++;\n+\n+\treturn;\n }\n \n void SetSp()\n', 'commit_subject': 'Finish VSyncFunc();', 'repo_name': 'TOMB5/TOMB5', 'committer': {'name': 'Gh0stBlade', 'email': 'e020a28481d6ea9c8705fd42bfef7223298404eb@live.com', 'time_sec': '1502990090', 'tz_offset': '60', 'date': {'seconds': '1502990090'}}, 'commit_tree': 'd2763368bc175612b44bea0b7c1c4f76b4abe7cd', 'commit_message': 'Finish VSyncFunc();\n', 'language_name': 'Python', 'license': 'mit', 'hunks': '@@ -31,14 +31,10 @@ static char XARepeat;\n int XAStartPos;\n static int XATrackList[17][2];\n \n-void /*$ra*/ cbvsync()\n-{ // line 2, offset 0x5d884\n-\t//int ret; // $a1\n-\t//unsigned char io[8]; // stack offset -16\n-\t{ // line 86, offset 0x5daec\n-\t\t//int cnt; // $v0\n-\t} // line 93, offset 0x5db20\n-} // line 120, offset 0x5dc10\n+void cbvsync()\n+{\n+\tS_Warn("[cbvsync] - Unimplemented!\\n");\n+}\n \n void InitNewCDSystem()//5DDE8, 5E264(<)\n {\n', 'addition_count': 4, 'deletion_count': 8, 'src_file': 'a/SPEC_PSXPC/CD.C', 'tgt_file': 'b/SPEC_PSXPC/CD.C', 'file_extension': '.C', 'before_file': '#include "CD.H"\n\n#include "CONTROL.H"\n#include "SPECIFIC.H"\n\n#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n//Number of XA files on disc (XA1-17.XA)\n#define NUM_XA_FILES 17\n\n#define XA_FILE_NAME "XA%d.XA"\n\n#define CDS "CDS!" + __TIMESTAMP__ + " ."\n\nunsigned short XATrackClip[] =//Probably used for XA audio start/end pos of each track\n{\n\t0xFF00, 0xFF00, 0xFE80, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF80,\n\t0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00,\n\t0xFE80, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF80, 0xFF80,\n\t0xFE00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFE00, 0xFF80, 0xFF80,\n\t0xFF00, 0xFF00, 0xFF80, 0xFF80, 0xFF00, 0xFF00, 0xFF00, 0xFF80,\n\t0xFF80, 0xFE00, 0xFF80, 0xFF00, 0xFF80, 0xFF80, 0xFF80, 0xFF80,\n\t0xFF00, 0xFF00, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF00,\n\t0xFE00, 0xFF00, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF00, 0xFF80,\n\t0xFE00, 0xFD80, 0xFD80, 0xFE80, 0xFE80, 0xFE80, 0xFF00, 0xFF80,\n\t0xFA00, 0xFC00, 0xFC00, 0xFC00, 0xFD80, 0xFF00, 0xFE00, 0xFF80,\n\t0xFE00, 0xFE00, 0xFD80, 0xFE80, 0xFF00, 0xFF00, 0xFF00, 0xFF00,\n\t0xFA00, 0xFB00, 0xFC00, 0xFB80, 0xFC80, 0xFC80, 0xFF00, 0xFFC0,\nint XAStartPos;\nstatic int XATrackList[17][2];\n\nvoid /*$ra*/ cbvsync()\n{ // line 2, offset 0x5d884\n\t//int ret; // $a1\n\t//unsigned char io[8]; // stack offset -16\n\t{ // line 86, offset 0x5daec\n\t\t//int cnt; // $v0\n\t} // line 93, offset 0x5db20\n} // line 120, offset 0x5dc10\n\nvoid InitNewCDSystem()//5DDE8, 5E264(<)\n{\nvolatile int XAEndPos;\nvolatile short XAVolume;\nvolatile short XAReqVolume;\nvolatile char XAFlag;\nshort XAMasterVolume;\nshort XATrack;\nshort XAReqTrack;\nchar XAWait;\nstatic char XARepeat;\nint XAStartPos;\nstatic int XATrackList[17][2];\n\n//Holds all game data file positions or offsets in GAMEWAD.OBJ.\nstruct GAMEWAD_header gwHeader;\n\n//LBA for the GAMEWAD.OBJ file on disc, this is set by InitNewCDSystem(), CDPosToInt() (See CD.C)\nint gwLba = 0;\n\n//Start sector for the current gamewad file entry.\nstatic int cdStartSector = 0;\n\n//Current sector for the gamewad file entry, updated as data is read from disk.\nint cdCurrentSector = 0;\n\nvoid CDDA_SetVolume(int nVolume)//5D7FC(<), 5DC78(<)\n{\n\tS_Warn("[CDDA_SetVolume] - Unimplemented!\\n");\n}\n\nvoid XAReplay()//5D838(<), 5DCB4(<)\n{\n#if 0\n\tCdlLOC loc;\n\n\tCdIntToPos(XAStartPos, &loc);\n\n\tif (CdControl(CdlReadS, (unsigned char*)&loc, NULL) == 1)\n\t{\n\t\tXACurPos = XAStartPos;\n\t}\n#endif\n\n\treturn;\n}\n\nvoid cbvsync()//5D884(<), 5DD00(<)\n{\n\tint ret;\n\tunsigned char io[8];\n\tint cnt;\n\n\tswitch (XAFlag)\n\t{\n\tcase 1:\n\t{\n\t\tif (XAVolume == 0)\n\t\t{\n\t\t\tXAFlag++;\n\t\t}\n\t\t//5DF9C\n\t\tbreak;\n\t}\n\tcase 2:\n\t{\n\t\tcnt = XATrack = XAReqTrack;\n\n\t\tif (XAReqTrack < 0)\n\t\t{\n\t\t\tcnt = XAReqTrack + 7;\n\t\t}\n\n\t\tcnt &= ~3;//>>3<<3\n\t\tXAStartPos = XATrackList[cnt][0];\n\t\tio[0] = 1;\n\t\tXAEndPos = XATrackList[cnt][1] + XATrackClip[XAReqTrack];\n\t\tXAStartPos = 0;\n\t\tio[1] = XATrack & 7;\n\t\tXACurPos = XAStartPos;\n\t\t//CdControlF(CdlSetfilter, &io[0]);\n\t\tXAFlag++;\n\n\t\tbreak;\n\t}\n\tcase 3:\n\t{\n\t\t//loc_5D980\n\t\tXAReplay();\n\t\tXAReqVolume = XAMasterVolume;\n\t\tXAFlag++;\n\n\t\tbreak;\n\t}\n\tcase 4:\n\t{\n\t\t//loc_5D9AC\n\t\tif (XAVolume == XAMasterVolume)\n\t\t{\n\t\t\tXAFlag++;\n\t\t\tXAWait = 60;\n\t\t}\n\n\t\tbreak;\n\t}\n\tcase 5:\n\t{\n\t\t//loc_5D9E0\n\t\tif (XAWait == 0)\n\t\t{\n\t\t\tXAFlag++;\n\t\t}\n\n\t\tXAWait--;\n\n\t\tbreak;\n\t}\n\tcase 6:\n\t{\n\t\t//loc_5DA18\n\t\tif (0)//(((VSync(-1)) & 7) == 0)\n\t\t{\n\t\t\t//ret = CdSync(1, &io[0]);\n\n\t\t\tif (ret == 5)\n\t\t\t{\n\t\t\t\tXAReplay();\n\t\t\t}\n\t\t\telse if (ret == 2)\n\t\t\t{\n\t\t\t\tif (XACurPos > XAEndPos)\n\t\t\t\t{\n\t\t\t\t\tif (XARepeat)\n\t\t\t\t\t{\n\t\t\t\t\t\tXAReplay();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (CurrentAtmosphere == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t//CdControlB(CdlPause, NULL, NULL);\n\t\t\t\t\t\t\tXAFlag = 7;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t//5DAB8\n\t\t\t\t\t\t\tXAVolume = 0;\n\t\t\t\t\t\t\tXARepeat = 1;\n\t\t\t\t\t\t\tXAFlag = ret;\n\t\t\t\t\t\t\tXAReqTrack = CurrentAtmosphere;\n\t\t\t\t\t\t\tCDDA_SetVolume(0);\n\t\t\t\t\t\t\tIsAtmospherePlaying = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t//5DAEC\n\t\t\t\t\t/*if (CdLastCom() == 0x11)\n\t\t\t\t\t{\n\t\t\t\t\t\tcnt = CdPosToInt((CdlLOC*) &io[5]);\n\t\t\t\t\t\tif (cnt > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tXACurPos = cnt;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tCdControlF(CdlGetlocP, NULL);*/\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\tcase 7:\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (XAVolume < XAReqVolume)\n\t{\n\t\tXAVolume += XAFadeRate;\n\n\t\tif (XAVolume > XAReqVolume)\n\t\t{\n\t\t\tXAVolume = XAReqVolume;\n\t\t}\n\n\t\tCDDA_SetVolume(XAVolume);\n\t}\n\telse if (XAReqVolume < XAVolume)\n\t{\n\t\tXAVolume -= XAFadeRate;\n\n\t\tif (XAReqVolume > XAVolume)\n\t\t{\n\t\t\tXAVolume = XAReqVolume;\n\t\t}\n\n\t\tCDDA_SetVolume(XAVolume);\n\t}\n\n\t//loc_5DC00\n\treturn;\n}\n\nvoid S_CDPlay(short track, int mode)//5DC10(<), 5E08C(<) (F)\n{\n\tunsigned char param[4];\n\n\tif (XATrack == -1)\n\t{\n\t\tparam[0] = 200;\n\t\t//CdControlB(CdlSetmode, &param[0], NULL);\n\t\t//VSync(3);\n\t\t//CdControlB(CdlPause, NULL, NULL);\n\t\tDEL_ChangeCDMode(1);\n\t}\n\n\tif (XATrack != track && XAReqTrack != track)\n\t{\n\t\tXAReqTrack = track;\n\t\tXARepeat = mode;\n\n\t\tif (XAFlag != 0)\n\t\t{\n\t\t\tXAFlag = 1;\n\t\t\tXAReqVolume = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tXAFlag = 2;\n\t\t}\n\t}\n\n\t//loc_5DCBC\n\treturn;\n}\n\nvoid S_CDStop()//5DCD0(<), 5E14C(<) (F) (*)\n{\n\tXAFlag = 0;\n\n\tXAReqTrack = -1;\n\tXATrack = -1;\n\n\tDEL_ChangeCDMode(0);\n\treturn;\n}\n\nvoid S_CDPause()//5DD14(<), 5E190(<) (F) (*)\n{\n\tif (XATrack >= 0)\n\t{\n\t\t//CdControlF(CdlPause, 0);\n\t}\n\n\treturn;\n}\n\nvoid S_CDRestart()//5DD40(<) (F) (*)\n{\n\tif (XATrack >= 0 && XAFlag != 7)\n\t{\n\t\t//CdControlF(CdlReadS, 0);\n\t}\n\n\treturn;\n}\n\nvoid S_StartSyncedAudio(int nTrack)//5DD78(<), 5E1F4(<) (F) (*)\n{\n\tIsAtmospherePlaying = 0;\n\n\tS_CDPlay(nTrack, 0);\n\n\twhile (XAFlag < 4) {}\n\n\t//VSync(29);\n\n\treturn;\n}\n\nvoid CDDA_SetMasterVolume(int nVolume)//5DDC4(<), 5E240(<) (F)\n{\n\tXAMasterVolume = nVolume;\n\tCDDA_SetVolume(nVolume);\n}\n\nvoid InitNewCDSystem()//5DDE8, 5E264(<) (F)\n{\n\tchar buf[10];\n\tint i = 0;\n\tlong local_wadfile_header[512];\n\n#if DISC_VERSION\n\tFILE* fileHandle = fopen(GAMEWAD_FILENAME, "rb");\n\tassert(fileHandle);\n\tfread(&local_wadfile_header, sizeof(struct GAMEWAD_header), 1, fileHandle);\n\tfclose(fileHandle);\n\n\tmemcpy(&gwHeader, &local_wadfile_header, sizeof(struct GAMEWAD_header));//5F6AC\n\n\t//FIXME: CdPosToInt(); returns LBA for GAMEWAD.OBJ on disc.\n\tgwLba = 24;\n#endif\n\n\t//loc_5E2E8\n\tfor (i = 0; i < NUM_XA_FILES; i++)\n\t{\n\t\tsprintf(buf, XA_FILE_NAME, i + 1);\n\t\tFILE* fileHandle = fopen(buf, "rb");\n\t\tassert(fileHandle);\n\t\tfseek(fileHandle, 0, SEEK_END);\n\t\tXATrackList[i][0] = -1;//FIXME: This value is returned by CdPosToInt(); register is v0. It returns the LBA of the XA file on disc.\n\t\tXATrackList[i][1] = ((ftell(fileHandle) + ((1 << CD_SECTOR_SHIFT) - 1)) >> CD_SECTOR_SHIFT) + XATrackList[i][0];\n\t\tfclose(fileHandle);\n\t}\n\n\tXAFlag = 0;\n\tXAVolume = 0;\n\tXAReqTrack = -1;\n\tXATrack = -1;\n}\n\nvoid DEL_ChangeCDMode(int mode)//5DEB0(<), 5E650 (F) (*)\n{\n\tunsigned char param[4];\n\n\tif (mode == 0)\n\t{\n\t\tif (current_cd_mode == 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tcurrent_cd_mode = 0;\n\n\t\t//param[0] = CdlModeSpeed;\n\t\t//CdControlB(CdlSetmode, param, 0);\n\t\t//VSync(3);\n\t}\n\telse if (mode == 1)\n\t{\n\t\t//loc_5DEF8\n\t\tif (current_cd_mode == mode)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tcurrent_cd_mode = mode;\n\t}\n\telse if (mode == 2)\n\t{\n\t\t//loc_5DF20\n\t\tif (current_cd_mode == mode)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tcurrent_cd_mode = mode;\n\n\t\t//param[0] = CdlModeSpeed;\n\t\t//CdControlB(CdlSetmode, param, 0);\n\t\t//VSync(3);\n\t}\n\n\t//loc_5DF58\n\treturn;\n}\n\n/*\n* [FUNCTIONALITY] - DEL_CDFS_OpenFile.\n* GAMEWAD_header is already in the memory at this point, we loaded it during InitNewCDSystem() (See CD.C)\n* This method initialises the CD\'s read sector for a specific gamewad entry.\n* File ID indices must match GAMEWAD.OBJ, see gw_files enum (GAMEWAD.H)\n* Note: A File ID of "NONE" or 0 will initialise the reader position back to 0.\n*\n* [USAGE]\n* @PARAM - [filenum] index into GAMEWAD_header.entries you wish to seek to.\n* @RETURN - Filesize of the gamewad entry in bytes.\n*/\n\nint DEL_CDFS_OpenFile(int filenum /*$a0*/)//*, 5E3C0(<) (F)\n{\n\tDEL_ChangeCDMode(0);\n\tcdCurrentSector = cdStartSector = (gwHeader.entries[filenum].fileOffset >> CD_SECTOR_SHIFT);\n\treturn gwHeader.entries[filenum].fileSize;\n}\n\n/*\n* [FUNCTIONALITY] - DEL_CDFS_Read\n* It is assumed that prior to calling this you have initialised the cd\'s\n* reader\'s position to the file entry you wish to read see (DEL_CDFS_OpenFile)\n* This method reads data from disc at it\'s last sectior/read position.\n*\n* [USAGE]\n* @PARAM - [size] the number of bytes you wish to read [addr] the memory location the data is read to.\n*/\n\nint DEL_CDFS_Read(char* addr, int size)//*, 5E414(<) (F) (*)\n{\n\tint i;\n\tint numSectorsToRead;\n\tint remainingDataToRead;\n\n\tFILE* fileHandle = NULL;\n\n\tfileHandle = fopen(GAMEWAD_FILENAME, "rb");\n\tassert(fileHandle);\n\tfseek(fileHandle, cdCurrentSector << CD_SECTOR_SHIFT, SEEK_SET);\n\n\tremainingDataToRead = size & ((1 << CD_SECTOR_SHIFT) - 1);\n\tnumSectorsToRead = size >> CD_SECTOR_SHIFT;\n\n\tif (numSectorsToRead != 0)\n\t{\n\t\tfor (i = 0; i < numSectorsToRead; i++)\n\t\t{\n\t\t\taddr += fread(addr, 1, CD_SECTOR_SIZE, fileHandle);\n\t\t}\n\n\t\tcdCurrentSector += numSectorsToRead;\n\t}\n\n\t//Another chunk that is not multiple of 2048 bytes exists, read it\n\tif (remainingDataToRead != 0)//%\n\t{\n\t\taddr += fread(addr, 1, remainingDataToRead, fileHandle);\n\t\tcdCurrentSector++;\n\t}\n\n\tfclose(fileHandle);\n\n\treturn 0;\n}\n\n/*\n* [FUNCTIONALITY] - DEL_CDFS_Seek\n* Seeks from the cd reader\'s current position.\n* Note: Negative numbers will allow backwards traversal.\n* [USAGE]\n* @PARAM - [offset] the number of bytes you wish to seek (not in sectors).\n*/\n\nint DEL_CDFS_Seek(int offset /*$a0*/)//*, 5E54C(<) (F) (*)\n{\n\tcdCurrentSector = cdStartSector + (offset >> CD_SECTOR_SHIFT);\n\treturn 0;\n}\n\n/*\n* [FUNCTIONALITY] - FRIG_CD_POS_TO_CUR\n* Updates the cd reader\'s start sector to current reader position.\n*/\n\nvoid FRIG_CD_POS_TO_CUR()//*, 5E564(<) (F) (*)\n{\n\tcdStartSector = cdCurrentSector;\n}', 'message': 'Finish VSyncFunc();\n', 'author_name': 'Gh0stBlade', 'lang': 'C'}