This commit is contained in:
iq_132 2019-02-14 23:01:35 -05:00
commit 593201b5ed
24 changed files with 656 additions and 1565 deletions

View File

@ -5,7 +5,6 @@
#include <fstream>
#include <cstdio>
#include <cstring>*/
#include "burnint.h"
#include "ide.h"
#define DEBUG_ATA 0

View File

@ -2,6 +2,7 @@
#define IDE
#include <string>
#include "burnint.h"
namespace ide
{

View File

@ -17417,3 +17417,125 @@ struct BurnDriver BurnDrvKof98mix = {
kof98mixInit, NeoExit, NeoFrame, NeoRender, NeoScan, &NeoRecalcPalette,
0x1000, 304, 224, 4, 3
};
static struct BurnRomInfo kof98pfeRomDesc[] = {
{ "242pfe.p1", 0x100000, 0x23876d95, 1 | BRF_ESS | BRF_PRG }, // 1 68K code
{ "242pfe.p2", 0x400000, 0xadbaa852, 1 | BRF_ESS | BRF_PRG }, // 1 68K code
{ "242pfe.p3", 0x020000, 0x930ea34e, 1 | BRF_ESS | BRF_PRG }, // 1 68K code
{ "242pfe.s1", 0x020000, 0x7f4dbf23, 2 | BRF_GRA }, // 2 Text layer tiles / TC531000
{ "242hx73.c1", 0x800000, 0x379654a5, 3 | BRF_GRA }, // 3 Sprite data
{ "242hx73.c2", 0x800000, 0x9c71fa3d, 3 | BRF_GRA }, // 4
{ "242.c3", 0x800000, 0x22127b4f, 3 | BRF_GRA }, // 5
{ "242.c4", 0x800000, 0x0b4fa044, 3 | BRF_GRA }, // 6
{ "242.c5", 0x800000, 0x9d10bed3, 3 | BRF_GRA }, // 7
{ "242.c6", 0x800000, 0xda07b6a2, 3 | BRF_GRA }, // 8
{ "242pfe.c7", 0x800000, 0x02f09b2e, 3 | BRF_GRA }, // 9
{ "242pfe.c8", 0x800000, 0xd43ab3e6, 3 | BRF_GRA }, // 10
{ "242-mg1.m1", 0x040000, 0x4e7a6b1b, 4 | BRF_ESS | BRF_PRG }, // 11 Z80 code
{ "242.v1", 0x400000, 0xb9ea8051, 5 | BRF_SND }, // 12 Sound data
{ "242.v2", 0x400000, 0xcc11106e, 5 | BRF_SND }, // 13
{ "242.v3", 0x400000, 0x044ea4e1, 5 | BRF_SND }, // 14
{ "242.v4", 0x400000, 0x7985ea30, 5 | BRF_SND }, // 15
};
STDROMPICKEXT(kof98pfe, kof98pfe, neogeo)
STD_ROM_FN(kof98pfe)
static UINT8 *kof98pfeExtraROM;
static INT32 kof98pfeInit()
{
INT32 nRet = NeoInit();
if (nRet == 0) {
kof98pfeExtraROM = (UINT8*)BurnMalloc(0x20000);
if (BurnLoadRom(kof98pfeExtraROM, 2, 1)) return 1;
kof98pfeExtraROM[0x1af4] = 0x71;
kof98pfeExtraROM[0x1af5] = 0x4e;
kof98pfeExtraROM[0x1b19] = 0x60;
kof98pfeExtraROM[0x1ca3] = 0x60;
UINT16 *rom = (UINT16*)kof98pfeExtraROM;
for (INT32 i = 0; i < 0x20000/2; i++) {
if (rom[i] == 0x4e7d) rom[i] = 0x4e71;
if (rom[i] == 0x4e7c) rom[i] = 0x4e75;
}
rom = (UINT16*)Neo68KROMActive;
for (INT32 i = 0; i < 0x100000/2; i++) {
if (rom[i] == 0x4e7d) rom[i] = 0x4e71;
if (rom[i] == 0x4e7c) rom[i] = 0x4e75;
}
SekOpen(0);
SekMapMemory(kof98pfeExtraROM, 0x900000, 0x91ffff, MAP_ROM);
SekClose();
}
return nRet;
}
static INT32 kof98pfeExit()
{
BurnFree (kof98pfeExtraROM);
return NeoExit();
}
struct BurnDriver BurnDrvkof98pfe = {
"kof98pfe", "kof98", "neogeo", NULL, "2017",
"Kof'98 (Plus Final Edition)(2017-07-23)(Korean board)\0", NULL, "hack", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 2, HARDWARE_PREFIX_CARTRIDGE | HARDWARE_SNK_NEOGEO, GBF_VSFIGHT, FBF_KOF,
NULL, kof98pfeRomInfo, kof98pfeRomName, NULL, NULL, NULL, NULL, neogeoInputInfo, neogeoDIPInfo,
kof98pfeInit, kof98pfeExit, NeoFrame, NeoRender, NeoScan, &NeoRecalcPalette,
0x1000, 320, 224, 4, 3
};
static struct BurnRomInfo kof10thdRomDesc[] = {
{ "363d.p1", 0x800000, 0x30c82f4c, 1 | BRF_ESS | BRF_PRG }, // 1 68K code
{ "363d.s1", 0x020000, 0x3c757cb1, 2 | BRF_GRA }, // 2 Text layer tiles / TC531000
{ "kf10-c1a.bin", 0x400000, 0x3bbc0364, 3 | BRF_GRA }, // 3 Sprite data
{ "kf10-c2a.bin", 0x400000, 0x91230075, 3 | BRF_GRA }, // 4
{ "kf10-c1b.bin", 0x400000, 0xb5abfc28, 3 | BRF_GRA }, // 5
{ "kf10-c2b.bin", 0x400000, 0x6cc4c6e1, 3 | BRF_GRA }, // 6
{ "kf10-c3a.bin", 0x400000, 0x5b3d4a16, 3 | BRF_GRA }, // 7
{ "kf10-c4a.bin", 0x400000, 0xc6f3419b, 3 | BRF_GRA }, // 8
{ "kf10-c3b.bin", 0x400000, 0x9d2bba19, 3 | BRF_GRA }, // 9
{ "kf10-c4b.bin", 0x400000, 0x5a4050cb, 3 | BRF_GRA }, // 10
{ "kf10-c5a.bin", 0x400000, 0xa289d1e1, 3 | BRF_GRA }, // 11
{ "kf10-c6a.bin", 0x400000, 0xe6494b5d, 3 | BRF_GRA }, // 12
{ "kf10-c5b.bin", 0x400000, 0x404fff02, 3 | BRF_GRA }, // 13
{ "kf10-c6b.bin", 0x400000, 0xf2ccfc9e, 3 | BRF_GRA }, // 14
{ "kf10-c7a.bin", 0x400000, 0xbe79c5a8, 3 | BRF_GRA }, // 15
{ "kf10-c8a.bin", 0x400000, 0xa5952ca4, 3 | BRF_GRA }, // 16
{ "kf10-c7b.bin", 0x400000, 0x3fdb3542, 3 | BRF_GRA }, // 17
{ "kf10-c8b.bin", 0x400000, 0x661b7a52, 3 | BRF_GRA }, // 18
{ "kf10-m1.bin", 0x020000, 0xf6fab859, 4 | BRF_ESS | BRF_PRG }, // 19 Z80 code
{ "kf10-v1.bin", 0x800000, 0x0fc9a58d, 5 | BRF_SND }, // 20 Sound data
{ "kf10-v2.bin", 0x800000, 0xb8c475a4, 5 | BRF_SND }, // 21
};
STDROMPICKEXT(kof10thd, kof10thd, neogeo)
STD_ROM_FN(kof10thd)
struct BurnDriver BurnDrvkof10thd = {
"kof10thd", "kof2002", "neogeo", NULL, "200?",
"Kof 10th Anniversary (The King of Fighters 2002 bootleg / Fully Decrypted)\0", NULL, "hack", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 2, HARDWARE_PREFIX_CARTRIDGE | HARDWARE_SNK_NEOGEO, GBF_VSFIGHT, FBF_KOF,
NULL, kof10thdRomInfo, kof10thdRomName, NULL, NULL, NULL, NULL, neogeoInputInfo, neogeoDIPInfo,
NeoInit, NeoExit, NeoFrame, NeoRender, NeoScan, &NeoRecalcPalette,
0x1000, 304, 224, 4, 3
};

File diff suppressed because it is too large Load Diff

View File

@ -68,6 +68,8 @@ static UINT8 DrvDips[1];
static UINT8 DrvReset;
static UINT8 DrvInputs[6];
static INT32 is_shufshot = 0;
static INT16 DrvAnalogPort0 = 0;
static INT16 DrvAnalogPort1 = 0;
static INT16 DrvAnalogPort2 = 0;
@ -2206,7 +2208,8 @@ static void __fastcall common32_main_write_word(UINT32 address, UINT16 data)
return;
}
bprintf (0, _T("MWW: %5.5x, %4.4x\n"), address, data);
if ((address&0xffff00) != 0x61ff00)
bprintf (0, _T("MWW: %5.5x, %4.4x\n"), address, data);
}
static void __fastcall common32_main_write_byte(UINT32 address, UINT8 data)
@ -2274,7 +2277,8 @@ static void __fastcall common32_main_write_byte(UINT32 address, UINT8 data)
return;
}
bprintf (0, _T("MWB: %5.5x, %2.2x\n"), address, data);
if ((address&0xffff00) != 0x61ff00)
bprintf (0, _T("MWB: %5.5x, %2.2x\n"), address, data);
}
static UINT8 wcbowl_track_read(INT32 player)
@ -2287,6 +2291,17 @@ static UINT16 track_read_8bit(INT32 player)
return (BurnTrackballRead(player, 0) & 0xff) | ((BurnTrackballRead(player, 1) & 0xff) << 8);
}
static INT32 shufshot_weird_y(INT16 ana)
{
// todo: revisit at a later time.
// "git 'r dun"-style
if (ana > 1024) ana = 1024;
if (ana < -1024) ana = -1024;
ana /= 256; // -4 - +4
ana *= 0.9; // tone it down a bit..
return (ana);
}
static UINT32 track_read_4bit(INT32 player)
{
if (tb_last_read[player] != scanline) {
@ -2306,6 +2321,12 @@ static UINT32 track_read_4bit(INT32 player)
else if (dy > 0x80) dy -= 0x100;
if (dy > 7) dy = 7;
else if (dy < -7) dy = -7;
if (is_shufshot) {
// keep shufshot happy...
dy = shufshot_weird_y((player == 0) ? DrvAnalogPort1 : DrvAnalogPort3);
}
tb_effy[player] = (tb_effy[player] + dy) & 0xff;
INT32 upper = tb_effy[player] & 15;
@ -2812,8 +2833,9 @@ static INT32 DrvGetRoms(bool bLoad)
if (bLoad) {
if (BurnLoadRom(pSndLoad[bank] + 1, i, 2)) return 1;
}
if (nSndROMLen[1]) {
if (nSndROMLen[1] || is_shufshot) {
// wcbowl,wcbowldx,wcbowl{140,165,161,16} have bank1 and 0x200000 spacing
// shufshot has 0x200000 spacing but only bank0
pSndLoad[bank] += 0x200000;
} else {
pSndLoad[bank] += ri.nLen * 2;
@ -3000,6 +3022,8 @@ static INT32 DrvExit()
Trackball_Type = -1;
is_shufshot = 0;
return 0;
}
@ -4821,6 +4845,7 @@ STD_ROM_FN(shufshot)
static INT32 ShufshotInit()
{
Trackball_Type = TB_TYPE0;
is_shufshot = 1;
return Common32BitInit(0x111a, 1, 0);
}

View File

@ -150,6 +150,10 @@ TCHAR* LabelCheck(TCHAR* s, TCHAR* pszLabel);
TCHAR* ExtractFilename(TCHAR* fullname);
TCHAR* DriverToName(UINT32 nDrv);
UINT32 NameToDriver(TCHAR* szName);
TCHAR *StrReplace(TCHAR *str, TCHAR find, TCHAR replace);
TCHAR *StrLower(TCHAR *str);
TCHAR *FileExt(TCHAR *str);
bool IsFileExt(TCHAR *str, TCHAR *ext);
extern INT32 bDoGamma;
extern INT32 bHardwareGammaOnly;

View File

@ -477,3 +477,45 @@ UINT32 NameToDriver(TCHAR* szName)
return nDrv;
}
TCHAR *FileExt(TCHAR *str)
{
TCHAR *dot = _tcsrchr(str, _T('.'));
return (dot) ? StrLower(dot) : str;
}
bool IsFileExt(TCHAR *str, TCHAR *ext)
{
return (_tcsicmp(ext, FileExt(str)) == 0);
}
TCHAR *StrReplace(TCHAR *str, TCHAR find, TCHAR replace)
{
INT32 length = _tcslen(str);
for (INT32 i = 0; i < length; i++) {
if (str[i] == find) str[i] = replace;
}
return str;
}
// StrLower() - leaves str untouched, returns modified string
TCHAR *StrLower(TCHAR *str)
{
static TCHAR szBuffer[256] = _T("");
INT32 length = _tcslen(str);
if (length > 255) length = 255;
for (INT32 i = 0; i < length; i++) {
if (str[i] >= _T('A') && str[i] <= _T('Z'))
szBuffer[i] = (str[i] + _T(' '));
else
szBuffer[i] = str[i];
}
szBuffer[length] = 0;
return &szBuffer[0];
}

View File

@ -803,7 +803,7 @@ BEGIN
EDITTEXT IDC_NCD_TEXTPUBLISHER,64,245,286,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
EDITTEXT IDC_NCD_TEXTIMAGE,64,259,286,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
EDITTEXT IDC_NCD_TEXTAUDIO,64,273,50,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
CONTROL "Scan for ISO only",IDC_NCD_SISO_ONLY_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,442,255,71,10
// CONTROL "Scan for ISO only",IDC_NCD_SISO_ONLY_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,442,255,71,10
END
@ -977,7 +977,7 @@ BEGIN
MENUITEM "Start Neo Geo Multi-slot...\tCtrl+F6",MENU_START_NEOGEO_MVS
MENUITEM SEPARATOR
MENUITEM "Load Neo Geo CDZ game...\tCtrl+F8", MENU_LOAD_NEOCD
MENUITEM "Select CD image (ISO/CUE)...\tCtrl+Shift+F12", MENU_CDIMAGE
MENUITEM "Select CD image (CUE/CCD)...\tCtrl+Shift+F12", MENU_CDIMAGE
MENUITEM "Start Neo Geo CDZ...\tCtrl+Shift+F6", MENU_START_NEOGEO_CD
MENUITEM SEPARATOR
MENUITEM "Exit game\tCtrl+F4", MENU_QUIT, GRAYED

View File

@ -224,6 +224,7 @@ extern TCHAR szAppRomPaths[DIRS_MAX][MAX_PATH];
int DrvInit(int nDrvNum, bool bRestore);
int DrvInitCallback(); // Used when Burn library needs to load a game. DrvInit(nBurnSelect, false)
int DrvExit();
void NeoCDZRateChangeback();
// burn_shift
extern INT32 BurnShiftEnabled;

View File

@ -10,6 +10,8 @@ TCHAR szAppRomPaths[DIRS_MAX][MAX_PATH] = { { _T("") }, { _T("") }, { _T("") },
static bool bSaveRAM = false;
static INT32 nNeoCDZnAudSampleRateSave = 0;
static int DrvBzipOpen()
{
BzipOpen(false);
@ -118,6 +120,24 @@ int __cdecl DrvCartridgeAccess(BurnCartrigeCommand nCommand)
return 0;
}
void NeoCDZRateChangeback()
{
if (nNeoCDZnAudSampleRateSave != 0) {
bprintf(PRINT_IMPORTANT, _T("Switching sound rate back to user-selected %dhz\n"), nNeoCDZnAudSampleRateSave);
nAudSampleRate[nAudSelect] = nNeoCDZnAudSampleRateSave;
nNeoCDZnAudSampleRateSave = 0;
}
}
static void NeoCDZRateChange()
{
if (nAudSampleRate[nAudSelect] != 44100) {
nNeoCDZnAudSampleRateSave = nAudSampleRate[nAudSelect];
bprintf(PRINT_IMPORTANT, _T("Switching sound rate to 44100hz (from %dhz) as required by NeoGeo CDZ\n"), nNeoCDZnAudSampleRateSave);
nAudSampleRate[nAudSelect] = 44100; // force 44100hz for CDDA
}
}
int DrvInit(int nDrvNum, bool bRestore)
{
int nStatus;
@ -145,6 +165,8 @@ int DrvInit(int nDrvNum, bool bRestore)
POST_INITIALISE_MESSAGE;
return 0;
}
NeoCDZRateChange();
}
{ // Init input and audio, save blitter init for later. (reduce # of mode changes, nice for emu front-ends)
@ -168,6 +190,7 @@ int DrvInit(int nDrvNum, bool bRestore)
}
nStatus = DoLibInit(); // Init the Burn library's driver
if (nStatus) {
if (nStatus & 2) {
BurnDrvExit(); // Exit the driver
@ -178,6 +201,8 @@ int DrvInit(int nDrvNum, bool bRestore)
FBAPopupDisplay(PUF_TYPE_WARNING);
}
NeoCDZRateChangeback();
POST_INITIALISE_MESSAGE;
return 1;
}
@ -230,6 +255,8 @@ int DrvInitCallback()
int DrvExit()
{
if (bDrvOkay) {
NeoCDZRateChangeback();
StopReplay();
VidExit();

View File

@ -1043,6 +1043,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nShowCmd
}
}
NeoCDZRateChangeback(); // Change back temp CDZ rate before saving
ConfigAppSave(); // Save config for the application
AppExit(); // Exit the application

View File

@ -163,13 +163,13 @@ void iso9660_ReadOffset(unsigned char *Dest, FILE* fp, unsigned int lOffset, uns
if(fp == NULL) return;
if (Dest == NULL) return;
fseek(fp, lOffset, SEEK_SET);
fseek(fp, lOffset + 16, SEEK_SET);
fread(Dest, lLength, lSize, fp);
}
static void NeoCDList_iso9660_CheckDirRecord(FILE* fp, int nSector)
{
int nSectorLength = 2048;
int nSectorLength = 2352;
//int nFile = 0;
unsigned int lBytesRead = 0;
//int nLen = 0;
@ -213,7 +213,7 @@ static void NeoCDList_iso9660_CheckDirRecord(FILE* fp, int nSector)
iso9660_ReadOffset(nLenDR, fp, lOffset + 1, 1, sizeof(unsigned char));
if(nLenDR[0] < 0x22) {
lOffset += (2048 - lBytesRead);
lOffset += (nSectorLength - lBytesRead);
lBytesRead = 0;
bNewSector = true;
continue;
@ -234,7 +234,7 @@ static void NeoCDList_iso9660_CheckDirRecord(FILE* fp, int nSector)
unsigned int nValue = 0;
sscanf(szValue, "%x", &nValue);
iso9660_ReadOffset(Data, fp, nValue * 2048, 0x10a, sizeof(unsigned char));
iso9660_ReadOffset(Data, fp, nValue * nSectorLength, 0x10a, sizeof(unsigned char));
char szData[8];
sprintf(szData, "%c%c%c%c%c%c%c", Data[0x100], Data[0x101], Data[0x102], Data[0x103], Data[0x104], Data[0x105], Data[0x106]);
@ -346,7 +346,7 @@ static int NeoCDList_CheckISO(TCHAR* pszFile)
}
// Make sure we have a valid ISO file extension...
if(_tcsstr(pszFile, _T(".iso")) || _tcsstr(pszFile, _T(".ISO")) )
if (IsFileExt(pszFile, _T(".img")) || IsFileExt(pszFile, _T(".bin")))
{
FILE* fp = _tfopen(pszFile, _T("rb"));
if(fp)
@ -359,20 +359,18 @@ static int NeoCDList_CheckISO(TCHAR* pszFile)
fseek(fp, 0, SEEK_END);
unsigned int lSize = 0;
lSize = ftell(fp);
//rewind(fp);
fseek(fp, 0, SEEK_SET);
// If it has at least 16 sectors proceed
if(lSize > (2048 * 16))
if(lSize > (2352 * 16))
{
// Check for Standard ISO9660 Identifier
unsigned char IsoHeader[2048 * 16 + 1];
unsigned char IsoCheck[6];
fread(IsoHeader, 1, 2048 * 16 + 1, fp); // advance to sector 16 and PVD Field 2
fread(IsoCheck, 1, 5, fp); // get Standard Identifier Field from PVD
// advance to sector 16 and PVD Field 2
iso9660_ReadOffset(&IsoCheck[0], fp, 2352 * 16 + 1, 1, 5); // get Standard Identifier Field from PVD
// Verify that we have indeed a valid ISO9660 MODE1/2048
// Verify that we have indeed a valid ISO9660 MODE1/2352
if(!memcmp(IsoCheck, "CD001", 5))
{
//bprintf(PRINT_NORMAL, _T(" Standard ISO9660 Identifier Found. \n"));
@ -381,7 +379,7 @@ static int NeoCDList_CheckISO(TCHAR* pszFile)
// Get Volume Descriptor Header
memset(&vdh, 0, sizeof(vdh));
//memcpy(&vdh, iso9660_ReadOffset(fp, (2048 * 16), sizeof(vdh)), sizeof(vdh));
iso9660_ReadOffset((unsigned char*)&vdh, fp, 2048 * 16, 1, sizeof(vdh));
iso9660_ReadOffset((unsigned char*)&vdh, fp, 16 * 2352, 1, sizeof(vdh));
// Check for a valid Volume Descriptor Type
if(vdh.vdtype == 0x01)
@ -392,7 +390,7 @@ static int NeoCDList_CheckISO(TCHAR* pszFile)
iso9660_PVD pvd;
memset(&pvd, 0, sizeof(pvd));
//memcpy(&pvd, iso9660_ReadOffset(fp, (2048 * 16), sizeof(pvd)), sizeof(pvd));
iso9660_ReadOffset((unsigned char*)&pvd, fp, 2048 * 16, 1, sizeof(pvd));
iso9660_ReadOffset((unsigned char*)&pvd, fp, 2352 * 16, 1, sizeof(pvd));
// ROOT DIRECTORY RECORD
@ -409,13 +407,12 @@ static int NeoCDList_CheckISO(TCHAR* pszFile)
// Convert HEX string to Decimal
sscanf(szRootSector, "%X", &nRootSector);
#else
// Just read from the file directly at the correct offset (0x8000 + 0x9e for the start of the root directory record)
// Just read from the file directly at the correct offset (SECTOR_SIZE * 16 + 0x9e for the start of the root directory record)
unsigned char buffer[8];
char szRootSector[32];
unsigned int nRootSector = 0;
fseek(fp, 0x809e, SEEK_SET);
fread(buffer, 1, 8, fp);
iso9660_ReadOffset(&buffer[0], fp, 2352 * 16 + 0x9e, 1, 8);
sprintf(szRootSector, "%02x%02x%02x%02x", buffer[4], buffer[5], buffer[6], buffer[7]);
@ -459,10 +456,11 @@ int GetNeoGeoCD_Identifier()
}
// Make sure we have a valid ISO file extension...
if(_tcsstr(GetIsoPath(), _T(".iso")) || _tcsstr(GetIsoPath(), _T(".ISO")) )
if (IsFileExt(GetIsoPath(), _T(".img")) || IsFileExt(GetIsoPath(), _T(".bin")))
{
if(_tfopen(GetIsoPath(), _T("rb")))
{
bprintf(0, _T("NeoCDList: checking %s\n"), GetIsoPath());
// Read ISO and look for 68K ROM standard program header, ID is always there
// Note: This function works very quick, doesn't compromise performance :)
// it just read each sector first 264 bytes aproximately only.
@ -476,7 +474,7 @@ int GetNeoGeoCD_Identifier()
} else {
bprintf(PRINT_NORMAL, _T(" File doesn't have a valid ISO extension [ .iso / .ISO ] \n"));
bprintf(PRINT_NORMAL, _T(" File doesn't have a valid ISO extension [ .img / .bin ] \n"));
return 0;
}

View File

@ -51,6 +51,9 @@ struct GAMELIST {
GAMELIST ngcd_list[100];
int nListItems = 0;
// CD image stuff
const int nSectorLength = 2352;
// Add game to List
static int NeoCDList_AddGame(TCHAR* pszFile, unsigned int nGameID)
{
@ -158,7 +161,6 @@ static int NeoCDList_CheckDuplicates(HWND hList, unsigned int nID)
static void NeoCDList_iso9660_CheckDirRecord(HWND hList, TCHAR* pszFile, FILE* fp, int nSector)
{
int nSectorLength = 2048;
//int nFile = 0;
unsigned int lBytesRead = 0;
//int nLen = 0;
@ -207,7 +209,7 @@ static void NeoCDList_iso9660_CheckDirRecord(HWND hList, TCHAR* pszFile, FILE*
iso9660_ReadOffset(nLenDR, fp, lOffset + 1, 1, sizeof(unsigned char));
if(nLenDR[0] < 0x22) {
lOffset += (2048 - lBytesRead);
lOffset += (nSectorLength - lBytesRead);
lBytesRead = 0;
bNewSector = true;
continue;
@ -228,7 +230,7 @@ static void NeoCDList_iso9660_CheckDirRecord(HWND hList, TCHAR* pszFile, FILE*
unsigned int nValue = 0;
sscanf(szValue, "%x", &nValue);
iso9660_ReadOffset(Data, fp, nValue * 2048, 0x10a, sizeof(unsigned char));
iso9660_ReadOffset(Data, fp, nValue * nSectorLength, 0x10a, sizeof(unsigned char));
char szData[8];
sprintf(szData, "%c%c%c%c%c%c%c", Data[0x100], Data[0x101], Data[0x102], Data[0x103], Data[0x104], Data[0x105], Data[0x106]);
@ -249,6 +251,8 @@ static void NeoCDList_iso9660_CheckDirRecord(HWND hList, TCHAR* pszFile, FILE*
strncpy(File, File, LEN_FI[0]);
File[LEN_FI[0]] = 0;
//bprintf(0, _T("\n------------\n--------------> nID %X\n"), nID);
// King of Fighters '94, The (1994)(SNK)(JP)
// 10-6-1994 (P1.PRG)
if(nID == 0x0055 && Data[0x67] == 0xDE) {
@ -353,7 +357,7 @@ static int NeoCDList_CheckISO(HWND hList, TCHAR* pszFile)
}
// Make sure we have a valid ISO file extension...
if(_tcsstr(pszFile, _T(".iso")) || _tcsstr(pszFile, _T(".ISO")) )
if ( IsFileExt(pszFile, _T(".img")) || IsFileExt(pszFile, _T(".bin")) )
{
FILE* fp = _tfopen(pszFile, _T("rb"));
if(fp)
@ -369,16 +373,15 @@ static int NeoCDList_CheckISO(HWND hList, TCHAR* pszFile)
fseek(fp, 0, SEEK_SET);
// If it has at least 16 sectors proceed
if(lSize > (2048 * 16))
if(lSize > (nSectorLength * 16))
{
// Check for Standard ISO9660 Identifier
unsigned char IsoHeader[2048 * 16 + 1];
unsigned char IsoCheck[6];
fread(IsoHeader, 1, 2048 * 16 + 1, fp); // advance to sector 16 and PVD Field 2
fread(IsoCheck, 1, 5, fp); // get Standard Identifier Field from PVD
// advance to sector 16 and PVD Field 2
iso9660_ReadOffset(&IsoCheck[0], fp, 2352 * 16 + 1, 1, 5); // get Standard Identifier Field from PVD
// Verify that we have indeed a valid ISO9660 MODE1/2048
// Verify that we have indeed a valid ISO9660 MODE1/2352
if(!memcmp(IsoCheck, "CD001", 5))
{
//bprintf(PRINT_NORMAL, _T(" Standard ISO9660 Identifier Found. \n"));
@ -387,7 +390,7 @@ static int NeoCDList_CheckISO(HWND hList, TCHAR* pszFile)
// Get Volume Descriptor Header
memset(&vdh, 0, sizeof(vdh));
//memcpy(&vdh, iso9660_ReadOffset(fp, (2048 * 16), sizeof(vdh)), sizeof(vdh));
iso9660_ReadOffset((unsigned char*)&vdh, fp, 2048 * 16, 1, sizeof(vdh));
iso9660_ReadOffset((unsigned char*)&vdh, fp, 16 * 2352, 1, sizeof(vdh));
// Check for a valid Volume Descriptor Type
if(vdh.vdtype == 0x01)
@ -398,7 +401,7 @@ static int NeoCDList_CheckISO(HWND hList, TCHAR* pszFile)
iso9660_PVD pvd;
memset(&pvd, 0, sizeof(pvd));
//memcpy(&pvd, iso9660_ReadOffset(fp, (2048 * 16), sizeof(pvd)), sizeof(pvd));
iso9660_ReadOffset((unsigned char*)&pvd, fp, 2048 * 16, 1, sizeof(pvd));
iso9660_ReadOffset((unsigned char*)&pvd, fp, 2352 * 16, 1, sizeof(pvd));
// ROOT DIRECTORY RECORD
@ -415,13 +418,12 @@ static int NeoCDList_CheckISO(HWND hList, TCHAR* pszFile)
// Convert HEX string to Decimal
sscanf(szRootSector, "%X", &nRootSector);
#else
// Just read from the file directly at the correct offset (0x8000 + 0x9e for the start of the root directory record)
// Just read from the file directly at the correct offset (SECTOR_SIZE * 16 + 0x9e for the start of the root directory record)
unsigned char buffer[8];
char szRootSector[32];
unsigned int nRootSector = 0;
fseek(fp, 0x809e, SEEK_SET);
fread(buffer, 1, 8, fp);
iso9660_ReadOffset(&buffer[0], fp, 2352 * 16 + 0x9e, 1, 8);
sprintf(szRootSector, "%02x%02x%02x%02x", buffer[4], buffer[5], buffer[6], buffer[7]);
@ -491,9 +493,6 @@ static void NeoCDList_ScanDir(HWND hList, TCHAR* pszDirectory)
continue;
}
TCHAR* pszISO = NULL;
pszISO = (TCHAR*)malloc(sizeof(TCHAR) * 512);
bool bDone = false;
WIN32_FIND_DATA ffdSubDirectory;
@ -505,7 +504,6 @@ static void NeoCDList_ScanDir(HWND hList, TCHAR* pszDirectory)
if(!bNeoCDListScanOnlyISO)
{
// Scan sub-directory for CUE
_stprintf(szSubSearch, _T("%s%s/*.cue"), pszDirectory, ffdDirectory.cFileName);
@ -521,18 +519,20 @@ static void NeoCDList_ScanDir(HWND hList, TCHAR* pszDirectory)
if(!(ffdSubDirectory.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
// File is CUE
if(_tcsstr(ffdSubDirectory.cFileName, _T(".cue")) || _tcsstr(ffdSubDirectory.cFileName, _T(".CUE")))
if(IsFileExt(ffdSubDirectory.cFileName, _T(".cue")))
{
// Parse CUE
TCHAR szParse[512] = _T("\0");
_stprintf(szParse, _T("%s%s/%s"), pszDirectory, ffdDirectory.cFileName, ffdSubDirectory.cFileName);
_stprintf(szParse, _T("%s%s\\%s"), pszDirectory, ffdDirectory.cFileName, ffdSubDirectory.cFileName);
//MessageBox(NULL, szParse, _T(""), MB_OK);
pszISO = NeoCDList_ParseCUE( szParse );
TCHAR *pszISO = NeoCDList_ParseCUE( szParse );
TCHAR szISO[512] =_T("\0");
_stprintf(szISO, _T("%s%s/%s"), pszDirectory, ffdDirectory.cFileName, pszISO);
_stprintf(szISO, _T("%s%s\\%s"), pszDirectory, ffdDirectory.cFileName, pszISO);
free(pszISO);
NeoCDList_CheckISO(hList, szISO);
bDone = true;
@ -543,11 +543,6 @@ static void NeoCDList_ScanDir(HWND hList, TCHAR* pszDirectory)
} while(FindNextFile(hSubDirectory, &ffdSubDirectory));
}
if(pszISO) {
free(pszISO);
pszISO = NULL;
}
if(bDone) {
FindClose(hSubDirectory);
continue;
@ -562,7 +557,7 @@ static void NeoCDList_ScanDir(HWND hList, TCHAR* pszDirectory)
memset(&ffdSubDirectory, 0, sizeof(WIN32_FIND_DATA));
// Scan sub-directory for ISO
_stprintf(szSubSearch, _T("%s%s/*.iso"), pszDirectory, ffdDirectory.cFileName);
_stprintf(szSubSearch, _T("%s%s/*.*"), pszDirectory, ffdDirectory.cFileName);
hSubDirectory = FindFirstFile(szSubSearch, &ffdSubDirectory);
@ -576,10 +571,10 @@ static void NeoCDList_ScanDir(HWND hList, TCHAR* pszDirectory)
if(!(ffdSubDirectory.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
// File is ISO
if(_tcsstr(ffdSubDirectory.cFileName, _T(".iso")) || _tcsstr(ffdSubDirectory.cFileName, _T(".ISO")))
if ( IsFileExt(ffdSubDirectory.cFileName, _T(".img")) || IsFileExt(ffdSubDirectory.cFileName, _T(".bin")) )
{
TCHAR szISO[512] = _T("\0");
_stprintf(szISO, _T("%s%s/%s"), pszDirectory, ffdDirectory.cFileName, ffdSubDirectory.cFileName);
_stprintf(szISO, _T("%s%s\\%s"), pszDirectory, ffdDirectory.cFileName, ffdSubDirectory.cFileName);
NeoCDList_CheckISO(hList, szISO);
@ -605,9 +600,6 @@ static void NeoCDList_ScanSingleDir(HWND hList, TCHAR* pszDirectory)
// ListView_DeleteAllItems(hList);
//
TCHAR* pszISO = NULL;
pszISO = (TCHAR*)malloc(sizeof(TCHAR) * 512);
WIN32_FIND_DATA ffdDirectory;
HANDLE hDirectory = NULL;
@ -632,7 +624,7 @@ static void NeoCDList_ScanSingleDir(HWND hList, TCHAR* pszDirectory)
if(!(ffdDirectory.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
// File is CUE
if(_tcsstr(ffdDirectory.cFileName, _T(".cue")) || _tcsstr(ffdDirectory.cFileName, _T(".CUE")))
if(IsFileExt(ffdDirectory.cFileName, _T(".cue")))
{
// Parse CUE
TCHAR szParse[512] = _T("\0");
@ -640,10 +632,11 @@ static void NeoCDList_ScanSingleDir(HWND hList, TCHAR* pszDirectory)
//MessageBox(NULL, szParse, _T(""), MB_OK);
pszISO = NeoCDList_ParseCUE( szParse );
TCHAR *pszISO = NeoCDList_ParseCUE( szParse );
TCHAR szISO[512] =_T("\0");
_stprintf(szISO, _T("%s%s"), pszDirectory, pszISO);
free(pszISO);
NeoCDList_CheckISO(hList, szISO);
}
@ -662,7 +655,7 @@ static void NeoCDList_ScanSingleDir(HWND hList, TCHAR* pszDirectory)
memset(&ffdDirectory, 0, sizeof(WIN32_FIND_DATA));
// Scan directory for ISO
_stprintf(szSearch, _T("%s*.iso"), pszDirectory);
_stprintf(szSearch, _T("%s*.*"), pszDirectory);
hDirectory = FindFirstFile(szSearch, &ffdDirectory);
@ -676,7 +669,7 @@ static void NeoCDList_ScanSingleDir(HWND hList, TCHAR* pszDirectory)
if(!(ffdDirectory.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
// File is ISO
if(_tcsstr(ffdDirectory.cFileName, _T(".iso")) || _tcsstr(ffdDirectory.cFileName, _T(".ISO")))
if ( IsFileExt(ffdDirectory.cFileName, _T(".img")) || IsFileExt(ffdDirectory.cFileName, _T(".bin")) )
{
TCHAR szISO[512] = _T("\0");
_stprintf(szISO, _T("%s%s"), pszDirectory, ffdDirectory.cFileName);
@ -690,11 +683,6 @@ static void NeoCDList_ScanSingleDir(HWND hList, TCHAR* pszDirectory)
FindClose(hDirectory);
}
if (pszISO) {
free(pszISO);
pszISO = NULL;
}
// bProcessingList = false;
}
@ -728,11 +716,7 @@ static TCHAR* NeoCDList_ParseCUE(TCHAR* pszFile)
_fgetts(szBuffer, sizeof(szBuffer), fp);
// terminate string
szBuffer[260] = 0;
if(!*szBuffer) {
return NULL;
}
szBuffer[260] = 0; // ????
int nLength = 0;
nLength = _tcslen(szBuffer);
@ -769,7 +753,7 @@ static TCHAR* NeoCDList_ParseCUE(TCHAR* pszFile)
_tcscpy(ngcd_list[nListItems].szISOFile, pStart + 1);
}
if (!_tcsncmp(pEnd + 2, _T("WAVE"), 5)) {
/*if (!_tcsncmp(pEnd + 2, _T("WAVE"), 5)) {
if(!ngcd_list[nListItems].nAudioTracks) {
ngcd_list[nListItems].nAudioTracks = 0;
}
@ -777,7 +761,7 @@ static TCHAR* NeoCDList_ParseCUE(TCHAR* pszFile)
_tcscpy(ngcd_list[nListItems].szTracks[ngcd_list[nListItems].nAudioTracks], pStart + 1);
ngcd_list[nListItems].nAudioTracks++;
}
} */
}
}
if(fp) fclose(fp);
@ -1254,7 +1238,7 @@ static INT_PTR CALLBACK NeoCDList_WndProc(HWND hDlg, UINT Msg, WPARAM wParam, LP
SetFocus(hListView);
break;
}
#if 0
case IDC_NCD_SISO_ONLY_CHECK:
{
if(BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_NCD_SISO_ONLY_CHECK)) {
@ -1271,7 +1255,7 @@ static INT_PTR CALLBACK NeoCDList_WndProc(HWND hDlg, UINT Msg, WPARAM wParam, LP
SetFocus(hListView);
break;
}
#endif
case IDC_NCD_CANCEL_BUTTON:
{
NeoCDList_Clean();

View File

@ -1030,7 +1030,7 @@ static void OnCommand(HWND /*hDlg*/, int id, HWND /*hwndCtl*/, UINT codeNotify)
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hScrnWnd;
ofn.lpstrFile = CDEmuImage;
ofn.lpstrFile = StrReplace(CDEmuImage, _T('/'), _T('\\'));
ofn.nMaxFile = MAX_PATH;
ofn.lpstrTitle = szTitle;
ofn.lpstrFilter = szFilter;

View File

@ -1,5 +1,6 @@
// State dialog module
#include "burner.h"
#include "neocdlist.h"
extern bool bReplayDontClose;
int bDrvSaveAll = 0;
@ -27,7 +28,11 @@ int StatedAuto(int bSave)
static TCHAR szName[MAX_PATH] = _T("");
int nRet;
_stprintf(szName, _T("config/games/%s.fs"), BurnDrvGetText(DRV_NAME));
if (NeoCDInfo_ID()) {
_stprintf(szName, _T("config/games/ngcd_%s.fs"), NeoCDInfo_Text(DRV_NAME));
} else {
_stprintf(szName, _T("config/games/%s.fs"), BurnDrvGetText(DRV_NAME));
}
if (bSave == 0) {
nRet = BurnStateLoad(szName, bDrvSaveAll, NULL); // Load ram
@ -43,7 +48,11 @@ int StatedAuto(int bSave)
static void CreateStateName(int nSlot)
{
_stprintf(szChoice, _T("./savestates/%s slot %02x.fs"), BurnDrvGetText(DRV_NAME), nSlot);
if (NeoCDInfo_ID()) {
_stprintf(szChoice, _T("./savestates/ngcd_%s slot %02x.fs"), NeoCDInfo_Text(DRV_NAME), nSlot);
} else {
_stprintf(szChoice, _T("./savestates/%s slot %02x.fs"), BurnDrvGetText(DRV_NAME), nSlot);
}
}
int StatedUNDO(int nSlot)
@ -78,7 +87,11 @@ int StatedLoad(int nSlot)
CreateStateName(nSlot);
} else {
if (bDrvOkay) {
_stprintf(szChoice, _T("%s*.fs"), BurnDrvGetText(DRV_NAME));
if (NeoCDInfo_ID()) {
_stprintf(szChoice, _T("ngcd_%s*.fs"), NeoCDInfo_Text(DRV_NAME));
} else {
_stprintf(szChoice, _T("%s*.fs"), BurnDrvGetText(DRV_NAME));
}
} else {
_stprintf(szChoice, _T("savestate"));
}
@ -142,7 +155,11 @@ int StatedSave(int nSlot)
if (nSlot) {
CreateStateName(nSlot);
} else {
_stprintf(szChoice, _T("%s"), BurnDrvGetText(DRV_NAME));
if (NeoCDInfo_ID()) {
_stprintf(szChoice, _T("ngcd_%s"), NeoCDInfo_Text(DRV_NAME));
} else {
_stprintf(szChoice, _T("%s"), BurnDrvGetText(DRV_NAME));
}
MakeOfn(szFilter);
ofn.lpstrTitle = FBALoadStringEx(hAppInst, IDS_STATE_SAVE, true);
ofn.Flags |= OFN_OVERWRITEPROMPT;

View File

@ -21,7 +21,8 @@ struct ZetExt {
pZetReadHandler ZetRead;
pZetWriteHandler ZetWrite;
UINT8 BusReq;
UINT32 BusReq;
UINT32 ResetLine;
};
static INT32 nZetCyclesDone[MAX_Z80];
@ -216,7 +217,8 @@ INT32 ZetInit(INT32 nCPU)
ZetCPUContext[nCPU]->ZetRead = ZetDummyReadHandler;
ZetCPUContext[nCPU]->ZetWrite = ZetDummyWriteHandler;
ZetCPUContext[nCPU]->BusReq = 0;
// TODO: Z80Init() will set IX IY F regs with default value, so get them ...
ZetCPUContext[nCPU]->ResetLine = 0;
// Z80Init() will set IX IY F regs with default value, so get them ...
Z80GetContext(&ZetCPUContext[nCPU]->reg);
nZetCyclesDone[nCPU] = 0;
@ -265,6 +267,7 @@ INT32 ZetInit(INT32 nCount)
ZetCPUContext[i].ZetRead = ZetDummyReadHandler;
ZetCPUContext[i].ZetWrite = ZetDummyWriteHandler;
ZetCPUContext[i].BusReq = 0;
ZetCPUContext[i].ResetLine = 0;
// TODO: Z80Init() will set IX IY F regs with default value, so get them ...
Z80GetContext(&ZetCPUContext[i].reg);
@ -388,14 +391,10 @@ INT32 ZetRun(INT32 nCycles)
nCycles -= nDelayed;
}
if (ZetCPUContext[nOpenedCPU]->BusReq) {
nCycles += nDelayed;
nZetCyclesTotal += nCycles;
return nCycles;
if (!ZetCPUContext[nOpenedCPU]->BusReq && !ZetCPUContext[nOpenedCPU]->ResetLine) {
nCycles = Z80Execute(nCycles);
}
nCycles = Z80Execute(nCycles);
nCycles += nDelayed;
nZetCyclesTotal += nCycles;
@ -698,6 +697,7 @@ INT32 ZetScan(INT32 nAction)
SCAN_VAR(nZetCyclesDone[i]);
SCAN_VAR(nZetCyclesDelayed[i]);
SCAN_VAR(ZetCPUContext[i]->BusReq);
SCAN_VAR(ZetCPUContext[i]->ResetLine);
}
SCAN_VAR(nZetCyclesTotal);
@ -821,6 +821,32 @@ INT32 ZetGetBUSREQLine()
return ZetCPUContext[nOpenedCPU]->BusReq;
}
void ZetSetRESETLine(INT32 nStatus)
{
#if defined FBA_DEBUG
if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetSetRESETLine called without init\n"));
if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetSetRESETLine called when no CPU open\n"));
#endif
if (nOpenedCPU < 0) return;
if (ZetCPUContext[nOpenedCPU]->ResetLine && nStatus == 0) {
ZetReset();
}
ZetCPUContext[nOpenedCPU]->ResetLine = nStatus;
}
INT32 ZetGetRESETLine()
{
#if defined FBA_DEBUG
if (!DebugCPU_ZetInitted) bprintf(PRINT_ERROR, _T("ZetGetRESET called without init\n"));
if (nOpenedCPU == -1) bprintf(PRINT_ERROR, _T("ZetGetRESET called when no CPU open\n"));
#endif
return ZetCPUContext[nOpenedCPU]->ResetLine;
}
void ZetSetAF(INT32 n, UINT16 value)
{
ZetCPUContext[n]->reg.af.w.l = value;

View File

@ -81,6 +81,9 @@ void ZetSetEDFECallback(void (*pCallback)(Z80_Regs*));
void ZetSetBUSREQLine(INT32 nStatus);
INT32 ZetGetBUSREQLine();
void ZetSetRESETLine(INT32 nStatus);
INT32 ZetGetRESETLine();
void ZetCheatWriteROM(UINT32 a, UINT8 d); // cheat core
UINT8 ZetCheatRead(UINT32 a);

View File

@ -13,7 +13,7 @@ static InterfaceInfo CDEmuInfo = { NULL, NULL, NULL };
#elif defined BUILD_SDL
// CD emulation module
#elif defined (_XBOX)
extern struct CDEmuDo isowavDo;
extern struct CDEmuDo cdimgDo;
#endif
static struct CDEmuDo* pCDEmuDo[] =
@ -23,7 +23,7 @@ static struct CDEmuDo* pCDEmuDo[] =
#elif defined BUILD_SDL
// CD emulation module
#elif defined (_XBOX)
&isowavDo,
&cdimgDo,
#endif
};

View File

@ -5,6 +5,7 @@
// CD emulation module
enum CDEmuStatusValue { idle = 0, reading, playing, paused, seeking, fastforward, fastreverse };
enum CDEmuReadTOCFlags { CDEmuTOC_FIRSTLAST = 0x1000, CDEmuTOC_LASTMSF, CDEmuTOC_FIRSTINDEX };
extern TCHAR CDEmuImage[MAX_PATH];

View File

@ -2,7 +2,6 @@
// .bin/.cue re-work by dink
#include "burner.h"
#include "io.h"
const int MAXIMUM_NUMBER_TRACKS = 100;
@ -16,7 +15,6 @@ const int CD_TYPE_CCD = 1 << 2;
static int cd_pregap;
struct MSF { UINT8 M; UINT8 S; UINT8 F; };
struct MSFAddress { UINT8 Control; MSF MSF; };
struct cdimgTRACK_DATA { UINT8 Control; UINT8 TrackNumber; UINT8 Address[4]; UINT8 EndAddress[4]; };
struct cdimgCDROM_TOC { UINT8 FirstTrack; UINT8 LastTrack; UINT8 ImageType; TCHAR Image[MAX_PATH]; cdimgTRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]; };
@ -160,6 +158,21 @@ static void cdimgPrintImageInfo()
}
}
static void cdimgAddLastTrack()
{ // Make a fake last-track w/total image size (for bounds checking)
FILE* h = _wfopen(cdimgTOC->Image, _T("rb"));
if (h)
{
fseek(h, 0, SEEK_END);
const UINT8* address = cdimgLBAToMSF(((ftell(h) + 2351) / 2352) + cd_pregap);
fclose(h);
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[1] = address[1];
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[2] = address[2];
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[3] = address[3];
}
}
// parse .sub file and build a TOC based in Q sub channel data
static int cdimgParseSubFile()
{
@ -177,9 +190,9 @@ static int cdimgParseSubFile()
length = _tcslen(filename_sub);
if (length <= 4 ||
(_tcscmp(_T(".ccd"), filename_sub + length - 4) &&
_tcscmp(_T(".img"), filename_sub + length - 4) &&
_tcscmp(_T(".sub"), filename_sub + length - 4)))
(!IsFileExt(filename_sub, _T(".ccd")) &&
!IsFileExt(filename_sub, _T(".img")) &&
!IsFileExt(filename_sub, _T(".sub"))))
{
dprintf(_T("*** Bad image: %s\n"), filename_sub);
return 1;
@ -259,19 +272,7 @@ static int cdimgParseSubFile()
cd_pregap = QChannel[0].MSFabs.F + QChannel[0].MSFabs.S * CD_FRAMES_SECOND + QChannel[0].MSFabs.M * CD_FRAMES_MINUTE;
//bprintf(0, _T("pregap lba: %d MSF: %d:%d:%d\n"), cd_pregap, QChannel[0].MSFabs.M, QChannel[0].MSFabs.S, QChannel[0].MSFabs.F);
{ // Make a fake last-track w/total image size (for bounds checking)
h = _wfopen(cdimgTOC->Image, _T("rb"));
if (h)
{
fseek(h, 0, SEEK_END);
const UINT8* address = cdimgLBAToMSF((ftell(h) + 2351) / 2352);
fclose(h);
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[1] = address[1];
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[2] = address[2];
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[3] = address[3];
}
}
cdimgAddLastTrack();
return 0;
}
@ -331,7 +332,7 @@ static int cdimgParseCueFile()
QuoteRead(&szQuote, NULL, s);
_sntprintf(szFile, ExtractFilename(CDEmuImage) - CDEmuImage, _T("%s"), CDEmuImage);
_sntprintf(szFile + (ExtractFilename(CDEmuImage) - CDEmuImage), 1024 - (ExtractFilename(CDEmuImage) - CDEmuImage), _T("/%s"), szQuote);
_sntprintf(szFile + (ExtractFilename(CDEmuImage) - CDEmuImage), 1024 - (ExtractFilename(CDEmuImage) - CDEmuImage), _T("\\%s"), szQuote);
if (track == 1) {
//bprintf(0, _T("Image file (from .CUE): %s\n"), szFile);
@ -421,19 +422,7 @@ static int cdimgParseCueFile()
fclose(h);
{
h = _wfopen(cdimgTOC->Image, _T("rb"));
if (h)
{
fseek(h, 0, SEEK_END);
const UINT8* address = cdimgLBAToMSF((ftell(h) + 2351) / 2352);
fclose(h);
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[1] = address[1];
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[2] = address[2];
cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[3] = address[3];
}
}
cdimgAddLastTrack();
return 0;
}
@ -477,7 +466,7 @@ static int cdimgInit()
if (_tcslen(filename) < 4)
return 1;
if (_tcscmp(_T(".cue"), filename + _tcslen(filename) - 4) == 0)
if (IsFileExt(filename, _T(".cue")))
{
if (cdimgParseCueFile())
{
@ -488,7 +477,7 @@ static int cdimgInit()
}
} else
if (_tcscmp(_T(".ccd"), filename + _tcslen(filename) - 4) == 0)
if (IsFileExt(filename, _T(".ccd")))
{
if (cdimgParseSubFile())
{
@ -615,7 +604,8 @@ static int cdimgPlay(UINT8 M, UINT8 S, UINT8 F)
{
const UINT8 address[] = { 0, M, S, F };
dprintf(_T(" play %02i:%02i:%02i\n"), M, S, F);
const UINT8* displayaddress = dinkLBAToMSF(cdimgMSFToLBA(address));
dprintf(_T(" play %02i:%02i:%02i\n"), displayaddress[1], displayaddress[2], displayaddress[3]);
return cdimgPlayLBA(cdimgMSFToLBA(address));
}
@ -675,7 +665,7 @@ static UINT8* cdimgReadTOC(int track)
{
static UINT8 TOCEntry[4];
if (track == -1)
if (track == CDEmuTOC_FIRSTLAST)
{
TOCEntry[0] = tobcd(cdimgTOC->FirstTrack - 1);
TOCEntry[1] = tobcd(cdimgTOC->LastTrack);
@ -684,7 +674,7 @@ static UINT8* cdimgReadTOC(int track)
return TOCEntry;
}
if (track == -2)
if (track == CDEmuTOC_LASTMSF)
{
TOCEntry[0] = cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[1];
TOCEntry[1] = cdimgTOC->TrackData[cdimgTOC->LastTrack].Address[2];
@ -694,6 +684,21 @@ static UINT8* cdimgReadTOC(int track)
return TOCEntry;
}
if (track == CDEmuTOC_FIRSTINDEX)
{
if (cdimgLBA < cdimgMSFToLBA(cdimgTOC->TrackData[cdimgTOC->FirstTrack].Address))
{
const UINT8* addressUNBCD = dinkLBAToMSF(cdimgLBA);
UINT8 index = ((addressUNBCD[1] * 60) + (addressUNBCD[2] + 4)) / 4;
TOCEntry[0] = tobcd((index < 100) ? index : 99);
}
else
{
TOCEntry[0] = tobcd(1);
}
return TOCEntry;
}
track = bcd(track);
if (track >= cdimgTOC->FirstTrack - 1 && track <= cdimgTOC->LastTrack)
@ -787,6 +792,17 @@ static int cdimgGetSoundBuffer(short* buffer, int samples)
cdimgPlayLBA(cdimgLBA); */
}
#if 0
extern int counter;
if (counter) {
const UINT8* displayaddress = dinkLBAToMSF(cdimgLBA);
dprintf(_T(" index %02i:%02i:%02i"), displayaddress[1], displayaddress[2], displayaddress[3]);
INT32 endt = cdimgMSFToLBA(cdimgTOC->TrackData[cdimgTrack + 1 /* next track */].Address);
const UINT8* displayaddressend = dinkLBAToMSF(endt);
dprintf(_T(" end %02i:%02i:%02i\n"), displayaddressend[1], displayaddressend[2], displayaddressend[3]);
}
#endif
if (cdimgFile == NULL) { // restart play if fileptr lost
bprintf(0, _T("CDDA file pointer lost, re-starting!\n"));
if (cdimgLBA < cdimgMSFToLBA(cdimgTOC->TrackData[cdimgTrack + 1].Address))
@ -798,6 +814,12 @@ static int cdimgGetSoundBuffer(short* buffer, int samples)
return 0;
}
if (cdimgLBA >= cdimgMSFToLBA(cdimgTOC->TrackData[cdimgTrack + 1 /* next track */].Address)) {
bprintf(0, _T("End of audio track %d reached!! stopping.\n"), cdimgTrack + 1);
cdimgStop();
return 0;
}
if ((cdimgOutputPosition + samples) >= cdimgOutputbufferSize)
{
short* src = cdimgOutputbuffer + cdimgOutputPosition * 2;
@ -813,14 +835,8 @@ static int cdimgGetSoundBuffer(short* buffer, int samples)
samples -= (cdimgOutputbufferSize - cdimgOutputPosition);
cdimgOutputPosition = 0;
cdimgLBA++;
if ((cdimgOutputbufferSize = fread(cdimgOutputbuffer, 4, cdimgOUT_SIZE, cdimgFile)) <= 0)
cdimgStop();
if (cdimgLBA >= cdimgMSFToLBA(cdimgTOC->TrackData[cdimgTrack + 1 /* next track */].Address)) {
bprintf(0, _T("End of audio track %d reached!! stopping.\n"), cdimgTrack + 1);
cdimgStop();
}
}
if ((cdimgOutputPosition + samples) < cdimgOutputbufferSize)

View File

@ -1,595 +0,0 @@
// ----------------------------------------------------------------------------
// iso/cue/wav support
/*-----------------------------------------------------------------------------
Modified by: CaptainCPS-X
Updates:
(10/24/2011)
- removed libmad and MP3 support
- added my custom DirectSound library to add WAV support
- removed most (if not all) references to MP3
- modified a few other things as needed
------------------------------------------------------------------------------*/
#include "burner.h"
#include "cdsound.h"
#define MAXIMUM_NUMBER_TRACKS (100)
#define CD_FRAMES_MINUTE (60 * 75)
#define CD_FRAMES_SECOND ( 75)
#define CD_FRAMES_PREGAP ( 2 * 75)
struct isowavTRACK_DATA {
char Control;
char TrackNumber;
char Address[4];
TCHAR* Filename;
};
struct isowavCDROM_TOC {
char FirstTrack;
char LastTrack;
isowavTRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
};
static isowavCDROM_TOC* isowavTOC;
static FILE* isowavFile = NULL;
static int isowavTrack = 0;
static int isowavLBA = 0;
// -----------------------------------------------------------------------------
static const char* isowavLBAToMSF(const int LBA)
{
static char address[4];
address[0] = 0;
address[1] = LBA / CD_FRAMES_MINUTE;
address[2] = LBA % CD_FRAMES_MINUTE / CD_FRAMES_SECOND;
address[3] = LBA % CD_FRAMES_SECOND;
return address;
}
static int isowavMSFToLBA(const char* address)
{
int LBA;
LBA = address[3];
LBA += address[2] * CD_FRAMES_SECOND;
LBA += address[1] * CD_FRAMES_MINUTE;
return LBA;
}
// -----------------------------------------------------------------------------
static int isowavGetTrackSizes()
{
// determine the lenght of the .iso / .mp3 files to complete the TOC
FILE* h;
for (int i = isowavTOC->FirstTrack - 1; i < isowavTOC->LastTrack; i++) {
const char* address;
if (isowavTOC->TrackData[i].Control & 4) {
// data track
h = _tfopen(isowavTOC->TrackData[i].Filename, _T("rb"));
if (h == NULL) return 1;
fseek(h, 0, SEEK_END);
address = isowavLBAToMSF((ftell(h) + 2047) / 2048 + isowavMSFToLBA(isowavTOC->TrackData[i].Address));
if(h) fclose(h);
} else {
// audio track
h = _tfopen(isowavTOC->TrackData[i].Filename, _T("rb"));
if (h == NULL)return 1;
fseek(h, 0, SEEK_END);
address = isowavLBAToMSF(((ftell(h) + 2047) / 2048) + isowavMSFToLBA(isowavTOC->TrackData[i].Address));
if(h) fclose(h);
}
isowavTOC->TrackData[i + 1].Address[0] += 0; // always 0 [?]
isowavTOC->TrackData[i + 1].Address[1] += address[1]; // M
isowavTOC->TrackData[i + 1].Address[2] += address[2]; // S
isowavTOC->TrackData[i + 1].Address[3] += address[3]; // F
}
return 0;
}
static int isowavTestISO()
{
TCHAR fullname[MAX_PATH];
TCHAR* filename;
int length = 0;
int offset = 0;
int track = 2;
FILE* h;
_tcscpy(fullname, CDEmuImage);
length = _tcslen(fullname);
// assume CD-ROM mode1/2048 format
if (length <= 4 && (_tcscmp(_T(".iso"), fullname + length - 4) || _tcscmp(_T(".bin"), fullname + length - 4))) {
return 1;
}
// create a TOC with only the data track first
isowavTOC->FirstTrack = 1;
isowavTOC->LastTrack = 1;
isowavTOC->TrackData[0].TrackNumber = 1;
isowavTOC->TrackData[0].Address[1] = 0;
isowavTOC->TrackData[0].Address[2] = 2;
isowavTOC->TrackData[0].Address[3] = 0;
isowavTOC->TrackData[0].Filename = (TCHAR*)malloc((length + 1) * sizeof(TCHAR));
if (isowavTOC->TrackData[0].Filename == NULL) {
return 1;
}
_tcscpy(isowavTOC->TrackData[0].Filename, fullname);
isowavTOC->TrackData[0].Control = 4;
// if the filename has a number in it, try to find .mp3 tracks
filename = ExtractFilename(fullname);
offset = (filename - fullname) + length - 6;
while (offset >= 0 && fullname[offset] != _T('0') && fullname[offset + 1] != _T('1')) {
offset--;
}
if (offset < 0) {
return isowavGetTrackSizes();
}
_stprintf(fullname + length - 4, _T(".wav"));
while (1) {
fullname[offset] = _T('0') + track / 10; fullname[offset + 1] = _T('0') + track % 10;
if ((h = _tfopen(fullname, _T("rb"))) == NULL) {
break;
}
fclose(h);
isowavTOC->TrackData[track - 1].TrackNumber = track;
isowavTOC->TrackData[track - 1].Filename = (TCHAR*)malloc((length + 1) * sizeof(TCHAR));
if (isowavTOC->TrackData[track - 1].Filename == NULL) {
return 1;
}
_tcscpy(isowavTOC->TrackData[track - 1].Filename, fullname);
isowavTOC->LastTrack = track;
track++;
}
return isowavGetTrackSizes();
}
static int isowavParseCueFile()
{
TCHAR szLine[1024];
TCHAR szFile[1024];
TCHAR* s;
TCHAR* t;
FILE* h;
int track = 0;
int length;
isowavTOC->FirstTrack = 1;
isowavTOC->LastTrack = 1;
isowavTOC->TrackData[0].Address[1] = 0;
isowavTOC->TrackData[0].Address[2] = 2;
isowavTOC->TrackData[0].Address[3] = 0;
h = _tfopen(CDEmuImage, _T("rt"));
if (h == NULL) {
return 1;
}
while (1) {
if (_fgetts(szLine, sizeof(szLine), h) == NULL) {
break;
}
length = _tcslen(szLine);
// get rid of the linefeed at the end
while (length && (szLine[length - 1] == _T('\r') || szLine[length - 1] == _T('\n'))) {
szLine[length - 1] = 0;
length--;
}
s = szLine;
// file info
if ((t = LabelCheck(s, _T("FILE"))) != 0) {
s = t;
TCHAR* szQuote;
// read filename
QuoteRead(&szQuote, NULL, s);
_sntprintf(szFile, ExtractFilename(CDEmuImage) - CDEmuImage, _T("%s"), CDEmuImage);
_sntprintf(szFile + (ExtractFilename(CDEmuImage) - CDEmuImage), 1024 - (ExtractFilename(CDEmuImage) - CDEmuImage), _T("/%s"), szQuote);
continue;
}
// track info
if ((t = LabelCheck(s, _T("TRACK"))) != 0) {
s = t;
// track number
track = _tcstol(s, &t, 10);
if (track < 1 || track > MAXIMUM_NUMBER_TRACKS) {
fclose(h);
return 1;
}
if (track < isowavTOC->FirstTrack) {
isowavTOC->FirstTrack = track;
}
if (track > isowavTOC->LastTrack) {
isowavTOC->LastTrack = track;
}
isowavTOC->TrackData[track - 1].TrackNumber = track;
isowavTOC->TrackData[track - 1].Filename = (TCHAR*)malloc((_tcslen(szFile) + 1) * sizeof(TCHAR));
if (isowavTOC->TrackData[track - 1].Filename == NULL) {
fclose(h);
return 1;
}
_tcscpy(isowavTOC->TrackData[track - 1].Filename, szFile);
s = t;
// type of track
if ((t = LabelCheck(s, _T("MODE1/2048"))) != 0) {
isowavTOC->TrackData[track - 1].Control = 4;
continue;
}
if ((t = LabelCheck(s, _T("AUDIO"))) != 0) {
isowavTOC->TrackData[track - 1].Control = 0;
continue;
}
fclose(h);
return 1;
}
// pregap
if ((t = LabelCheck(s, _T("PREGAP"))) != 0) {
s = t;
int M, S, F;
// pregap M
M = _tcstol(s, &t, 10);
s = t + 1;
// pregap S
S = _tcstol(s, &t, 10);
s = t + 1;
// pregap F
F = _tcstol(s, &t, 10);
if (M < 0 || M > 100 || S < 0 || S > 59 || F < 0 || F > 74) {
fclose(h);
return 1;
}
isowavTOC->TrackData[track - 1].Address[1] = M;
isowavTOC->TrackData[track - 1].Address[2] = S;
isowavTOC->TrackData[track - 1].Address[3] = F;
continue;
}
}
fclose(h);
return isowavGetTrackSizes();
}
// -----------------------------------------------------------------------------
static int isowavExit()
{
wav_exit();
if (isowavFile) {
fclose(isowavFile);
isowavFile = NULL;
}
isowavTrack = 0;
isowavLBA = 0;
if (isowavTOC) {
for (int i = 0; i < MAXIMUM_NUMBER_TRACKS; i++) {
free(isowavTOC->TrackData[i].Filename);
}
free(isowavTOC);
isowavTOC = NULL;
}
return 0;
}
static int isowavInit()
{
wav_exit();
isowavTOC = (isowavCDROM_TOC*)malloc(sizeof(isowavCDROM_TOC));
if (isowavTOC == NULL) {
return 1;
}
memset(isowavTOC, 0, sizeof(isowavCDROM_TOC));
TCHAR* filename = ExtractFilename(CDEmuImage);
if (_tcslen(filename) < 4) {
return 1;
}
if (_tcscmp(_T(".cue"), filename + _tcslen(filename) - 4) == 0) {
if (isowavParseCueFile()) {
dprintf(_T("*** Couldn't parse .cue file\n"));
isowavExit();
return 1;
}
} else {
if (isowavTestISO()) {
dprintf(_T("*** Couldn't find .iso / .bin file\n"));
isowavExit();
return 1;
}
}
dprintf(_T(" CD image TOC read\n"));
for (int i = isowavTOC->FirstTrack - 1; i < isowavTOC->LastTrack; i++) {
dprintf(_T(" track %2i start %02i:%02i:%02i control 0x%02X %s\n"), isowavTOC->TrackData[i].TrackNumber, isowavTOC->TrackData[i].Address[1], isowavTOC->TrackData[i].Address[2], isowavTOC->TrackData[i].Address[3], isowavTOC->TrackData[i].Control, isowavTOC->TrackData[i].Filename);
}
dprintf(_T(" total running time %02i:%02i:%02i\n"), isowavTOC->TrackData[(int)isowavTOC->LastTrack].Address[1], isowavTOC->TrackData[(int)isowavTOC->LastTrack].Address[2], isowavTOC->TrackData[(int)isowavTOC->LastTrack].Address[3]);
CDEmuStatus = idle;
return 0;
}
TCHAR* GetIsoPath()
{
if(isowavTOC) {
return isowavTOC->TrackData[0].Filename;
}
return NULL;
}
static int isowavStop()
{
wav_stop();
if (isowavFile) {
fclose(isowavFile);
isowavFile = NULL;
}
CDEmuStatus = idle;
return 0;
}
static int isowavPlayLBA(int LBA)
{
isowavLBA = LBA;
for (isowavTrack = isowavTOC->FirstTrack - 1; isowavTrack < isowavTOC->LastTrack; isowavTrack++) {
if (isowavLBA < isowavMSFToLBA(isowavTOC->TrackData[isowavTrack + 1].Address)) {
break;
}
}
if (isowavTrack >= isowavTOC->LastTrack) {
return 1;
}
bprintf(PRINT_IMPORTANT, _T(" playing track %2i - %s\n"), isowavTrack + 1, isowavTOC->TrackData[isowavTrack].Filename);
isowavFile = _tfopen(isowavTOC->TrackData[isowavTrack].Filename, _T("rb"));
if (isowavFile == NULL) {
return 1;
}
if( _tcsstr(isowavTOC->TrackData[isowavTrack].Filename, _T(".wav")) || _tcsstr(isowavTOC->TrackData[isowavTrack].Filename, _T(".WAV"))) {
// is a wav, no need to keep this file pointer
if (isowavFile) {
fclose(isowavFile);
isowavFile = NULL;
}
if(wav_open(isowavTOC->TrackData[isowavTrack].Filename)) {
wav_play();
} else {
// error creating the WAV stream
return 1;
}
}
//dprintf(_T("*** WAV: wBitsPerSample: %d \n"), wav->g_pStreamingSound->m_pWaveFile->m_pwfx->wBitsPerSample);
//dprintf(_T("*** WAV: nAvgBytesPerSec: %d \n"), wav->g_pStreamingSound->m_pWaveFile->m_pwfx->nAvgBytesPerSec);
//dprintf(_T("*** WAV: m_dwSize: %d \n"), wav->g_pStreamingSound->m_pWaveFile->m_dwSize);
//dprintf(_T("*** WAV: nBlockAlign: %d \n"), wav->g_pStreamingSound->m_pWaveFile->m_pwfx->nBlockAlign);
isowavLBA = isowavMSFToLBA(isowavTOC->TrackData[isowavTrack].Address);
CDEmuStatus = playing;
return 0;
}
static int isowavPlay(unsigned char M, unsigned char S, unsigned char F)
{
const char address[] = { 0, M, S, F };
return isowavPlayLBA(isowavMSFToLBA(address));
}
static int isowavLoadSector(int LBA, char* pBuffer)
{
LBA += CD_FRAMES_PREGAP;
if (LBA != isowavLBA) {
int track;
for (track = isowavTOC->FirstTrack - 1; track < isowavTOC->LastTrack; track++) {
if (LBA < isowavMSFToLBA(isowavTOC->TrackData[track + 1].Address)) {
break;
}
}
if (isowavFile == NULL || track != isowavTrack) {
isowavStop();
isowavTrack = track;
bprintf(PRINT_IMPORTANT, _T(" reading track %2i - %s\n"), isowavTrack + 1, isowavTOC->TrackData[isowavTrack].Filename);
isowavFile = _tfopen(isowavTOC->TrackData[isowavTrack].Filename, _T("rb"));
if (isowavFile == NULL) {
return 0;
}
}
if (fseek(isowavFile, (LBA - isowavMSFToLBA(isowavTOC->TrackData[isowavTrack].Address)) * 2048, SEEK_SET)) {
dprintf(_T("*** couldn't seek\n"));
return 0;
}
isowavLBA = (ftell(isowavFile) + 2047) / 2048;
CDEmuStatus = reading;
}
if (fread(pBuffer, 1, 2048, isowavFile) <= 0) {
dprintf(_T("*** couldn't read from file\n"));
isowavStop();
return 0;
}
isowavLBA = isowavMSFToLBA(isowavTOC->TrackData[isowavTrack].Address) + (ftell(isowavFile) + 2047) / 2048;
return isowavLBA - CD_FRAMES_PREGAP;
}
static unsigned char* isowavReadTOC(int track)
{
static unsigned char TOCEntry[4];
if (track == -1) {
TOCEntry[0] = isowavTOC->FirstTrack - 1;
TOCEntry[1] = isowavTOC->LastTrack;
TOCEntry[2] = 0;
TOCEntry[3] = 0;
return TOCEntry;
}
if (track == -2) {
TOCEntry[0] = isowavTOC->TrackData[(int)isowavTOC->LastTrack].Address[1];
TOCEntry[1] = isowavTOC->TrackData[(int)isowavTOC->LastTrack].Address[2];
TOCEntry[2] = isowavTOC->TrackData[(int)isowavTOC->LastTrack].Address[3];
TOCEntry[3] = 0;
return TOCEntry;
}
if (track >= isowavTOC->FirstTrack - 1 && track <= isowavTOC->LastTrack) {
TOCEntry[0] = isowavTOC->TrackData[track - 1].Address[1];
TOCEntry[1] = isowavTOC->TrackData[track - 1].Address[2];
TOCEntry[2] = isowavTOC->TrackData[track - 1].Address[3];
TOCEntry[3] = isowavTOC->TrackData[track - 1].Control;
}
return TOCEntry;
}
static unsigned char* isowavReadQChannel()
{
static unsigned char QChannelData[8];
switch (CDEmuStatus) {
case reading:
case playing: {
const char* AddressAbs = isowavLBAToMSF(isowavLBA);
const char* AddressRel = isowavLBAToMSF(isowavLBA - isowavMSFToLBA(isowavTOC->TrackData[isowavTrack].Address));
QChannelData[0] = isowavTOC->TrackData[isowavTrack].TrackNumber;
QChannelData[1] = AddressAbs[1];
QChannelData[2] = AddressAbs[2];
QChannelData[3] = AddressAbs[3];
QChannelData[4] = AddressRel[1];
QChannelData[5] = AddressRel[2];
QChannelData[6] = AddressRel[3];
QChannelData[7] = isowavTOC->TrackData[isowavTrack].Control;
break;
}
case paused: {
break;
}
default: {
memset(QChannelData, 0, sizeof(QChannelData));
}
}
return QChannelData;
}
static int isowavGetSoundBuffer(short* /*buffer*/, int /*samples*/)
{
// ---------------------------------------------------------------------
// TODO:
// Port the old 'isomp3GetSoundBuffer()' function from 'cd_isomp3.cpp'
// to use WAVE stream data, porting that function will fix the
// 00:00 progress status on the main NeoGeo CD BIOS menu.
// ---------------------------------------------------------------------
return 0;
}
static int isowavGetSettings(InterfaceInfo* /*pInfo*/)
{
return 0;
}
struct CDEmuDo isowavDo = { isowavExit, isowavInit, isowavStop, isowavPlay, isowavLoadSector, isowavReadTOC, isowavReadQChannel, isowavGetSoundBuffer, isowavGetSettings, _T("cue/iso/wav CD emulation") };

View File

@ -1,433 +0,0 @@
#include "burner.h"
#include "cdsound.h"
WavClass::WavClass()
{
m_DirectSound = 0;
m_primaryBuffer = 0;
m_secondaryBuffer1 = 0;
}
WavClass::WavClass(const WavClass&)
{
//
}
WavClass::~WavClass()
{
//
}
bool WavClass::Initialize(HWND hwnd, TCHAR* szFile)
{
bool result;
// Initialize direct sound and the primary sound buffer.
result = InitializeDirectSound(hwnd);
if(!result)
{
return false;
}
// Load a wave audio file onto a secondary buffer.
result = LoadWaveFile(szFile, &m_secondaryBuffer1);
if(!result)
{
return false;
}
return true;
}
void WavClass::Shutdown()
{
// Release the secondary buffer.
ShutdownWaveFile(&m_secondaryBuffer1);
// Shutdown the Direct Sound API.
ShutdownDirectSound();
return;
}
bool WavClass::InitializeDirectSound(HWND hwnd)
{
HRESULT result;
DSBUFFERDESC bufferDesc;
WAVEFORMATEX waveFormat;
// Initialize the direct sound interface pointer for the default sound device.
result = _DirectSoundCreate(NULL, &m_DirectSound, NULL);
if(FAILED(result))
{
return false;
}
// Set the cooperative level to priority so the format of the primary sound buffer can be modified.
result = m_DirectSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
if(FAILED(result))
{
return false;
}
GUID guidNULL;
memset(&guidNULL,0,sizeof(GUID));
// Setup the primary buffer description.
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
bufferDesc.dwBufferBytes = 0;
bufferDesc.dwReserved = 0;
bufferDesc.lpwfxFormat = NULL;
bufferDesc.guid3DAlgorithm = guidNULL; //GUID_NULL;
// Get control of the primary sound buffer on the default sound device.
result = m_DirectSound->CreateSoundBuffer(&bufferDesc, &m_primaryBuffer, NULL);
if(FAILED(result))
{
return false;
}
// Setup the format of the primary sound bufffer.
// In this case it is a .WAV file recorded at 44,100 samples per second in 16-bit stereo (cd audio format).
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nSamplesPerSec = 44100;
waveFormat.wBitsPerSample = 16;
waveFormat.nChannels = 2;
waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
waveFormat.cbSize = 0;
// Set the primary buffer to be the wave format specified.
result = m_primaryBuffer->SetFormat(&waveFormat);
if(FAILED(result))
{
return false;
}
return true;
}
void WavClass::ShutdownDirectSound()
{
// Release the primary sound buffer pointer.
if(m_primaryBuffer)
{
m_primaryBuffer->Release();
m_primaryBuffer = 0;
}
// Release the direct sound interface pointer.
if(m_DirectSound)
{
m_DirectSound->Release();
m_DirectSound = 0;
}
return;
}
bool WavClass::LoadWaveFile(TCHAR* filename, IDirectSoundBuffer** secondaryBuffer)
{
FILE* filePtr;
unsigned int count;
WaveHeaderType waveFileHeader;
WAVEFORMATEX waveFormat;
DSBUFFERDESC bufferDesc;
HRESULT result;
IDirectSoundBuffer* tempBuffer;
unsigned char* waveData;
unsigned char* bufferPtr;
unsigned long bufferSize;
// Open the wave file in binary.
filePtr = _tfopen(filename, _T("rb"));
if(!filePtr)
{
return false;
}
// Read in the wave file header.
count = fread(&waveFileHeader, sizeof(waveFileHeader), 1, filePtr);
if(count != 1)
{
fclose(filePtr);
return false;
}
// Check that the chunk ID is the RIFF format.
if((waveFileHeader.chunkId[0] != 'R') || (waveFileHeader.chunkId[1] != 'I') ||
(waveFileHeader.chunkId[2] != 'F') || (waveFileHeader.chunkId[3] != 'F'))
{
fclose(filePtr);
return false;
}
// Check that the file format is the WAVE format.
if((waveFileHeader.format[0] != 'W') || (waveFileHeader.format[1] != 'A') ||
(waveFileHeader.format[2] != 'V') || (waveFileHeader.format[3] != 'E'))
{
fclose(filePtr);
return false;
}
// Check that the sub chunk ID is the fmt format.
if((waveFileHeader.subChunkId[0] != 'f') || (waveFileHeader.subChunkId[1] != 'm') ||
(waveFileHeader.subChunkId[2] != 't') || (waveFileHeader.subChunkId[3] != ' '))
{
fclose(filePtr);
return false;
}
// Check that the audio format is WAVE_FORMAT_PCM.
if(waveFileHeader.audioFormat != WAVE_FORMAT_PCM)
{
fclose(filePtr);
return false;
}
// Check that the wave file was recorded in stereo format.
if(waveFileHeader.numChannels != 2)
{
fclose(filePtr);
return false;
}
// Check that the wave file was recorded at a sample rate of 44.1 KHz.
if(waveFileHeader.sampleRate != 44100)
{
fclose(filePtr);
return false;
}
// Ensure that the wave file was recorded in 16 bit format.
if(waveFileHeader.bitsPerSample != 16)
{
fclose(filePtr);
return false;
}
// Check for the data chunk header.
if((waveFileHeader.dataChunkId[0] != 'd') || (waveFileHeader.dataChunkId[1] != 'a') ||
(waveFileHeader.dataChunkId[2] != 't') || (waveFileHeader.dataChunkId[3] != 'a'))
{
fclose(filePtr);
return false;
}
// Set the wave format of secondary buffer that this wave file will be loaded onto.
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nSamplesPerSec = 44100;
waveFormat.wBitsPerSample = 16;
waveFormat.nChannels = 2;
waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
waveFormat.cbSize = 0;
GUID guidNULL;
memset(&guidNULL,0,sizeof(GUID));
// Set the buffer description of the secondary sound buffer that the wave file will be loaded onto.
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY;
bufferDesc.dwBufferBytes = waveFileHeader.dataSize;
bufferDesc.dwReserved = 0;
bufferDesc.lpwfxFormat = &waveFormat;
bufferDesc.guid3DAlgorithm = guidNULL; //GUID_NULL;
// Create a temporary sound buffer with the specific buffer settings.
result = m_DirectSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL);
if(FAILED(result))
{
fclose(filePtr);
return false;
}
// Test the buffer format against the direct sound 8 interface and create the secondary buffer.
result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer, (void**)&*secondaryBuffer);
if(FAILED(result))
{
fclose(filePtr);
return false;
}
// Release the temporary buffer.
tempBuffer->Release();
tempBuffer = 0;
// Move to the beginning of the wave data which starts at the end of the data chunk header.
fseek(filePtr, sizeof(WaveHeaderType), SEEK_SET);
// Create a temporary buffer to hold the wave file data.
waveData = new unsigned char[waveFileHeader.dataSize];
if(!waveData)
{
fclose(filePtr);
return false;
}
// Read in the wave file data into the newly created buffer.
count = fread(waveData, 1, waveFileHeader.dataSize, filePtr);
if(count != waveFileHeader.dataSize)
{
delete [] waveData;
waveData = 0;
fclose(filePtr);
return false;
}
// Close the file once done reading.
int error = fclose(filePtr);
if(error != 0)
{
delete [] waveData;
waveData = 0;
return false;
}
// Lock the secondary buffer to write wave data into it.
result = (*secondaryBuffer)->Lock(0, waveFileHeader.dataSize, (void**)&bufferPtr, (DWORD*)&bufferSize, NULL, 0, 0);
if(FAILED(result))
{
delete [] waveData;
waveData = 0;
return false;
}
// Copy the wave data into the buffer.
memcpy(bufferPtr, waveData, waveFileHeader.dataSize);
// Unlock the secondary buffer after the data has been written to it.
result = (*secondaryBuffer)->Unlock((void*)bufferPtr, bufferSize, NULL, 0);
if(FAILED(result))
{
delete [] waveData;
waveData = 0;
return false;
}
// Release the wave data since it was copied into the secondary buffer.
delete [] waveData;
waveData = 0;
return true;
}
void WavClass::ShutdownWaveFile(IDirectSoundBuffer** secondaryBuffer)
{
// Release the secondary sound buffer.
if(*secondaryBuffer)
{
(*secondaryBuffer)->Release();
*secondaryBuffer = 0;
}
return;
}
#include "cd_interface.h"
WavClass* wav;
extern HWND hScrnWnd;
void wav_exit()
{
if(wav) {
wav_stop();
wav->Shutdown();
wav = NULL;
}
}
int wav_open(TCHAR* szFile)
{
wav_exit();
if(hScrnWnd) {
wav = new WavClass;
wav->Initialize(hScrnWnd, szFile);
} else {
return 0;
}
return 1;
}
void wav_stop()
{
if(!wav) return;
wav->GetSecondaryBuffer()->Stop();
wav->GetSecondaryBuffer()->SetCurrentPosition( 0 );
}
void wav_play()
{
if(!wav) return;
HRESULT result;
// Play the contents of the secondary sound buffer.
IDirectSoundBuffer* m_secondaryBuffer1 = wav->GetSecondaryBuffer();
if(!m_secondaryBuffer1) {
//
return;
}
// Set volume of the buffer to 100%.
result = m_secondaryBuffer1->SetVolume(DSBVOLUME_MAX);
if(FAILED(result))
{
return;
}
result = m_secondaryBuffer1->Play(0, 0, DSBPLAY_LOOPING);
if(FAILED(result)) {
//
return;
}
}
void wav_pause(bool bResume)
{
if(!wav) return;
if(!bResume)
{
DWORD pdwStatus;
wav->GetSecondaryBuffer()->GetStatus(&pdwStatus);
if((pdwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
HRESULT result;
result = wav->GetSecondaryBuffer()->Stop();
if(FAILED(result)) {
//
}
}
} else {
DWORD pdwStatus;
wav->GetSecondaryBuffer()->GetStatus(&pdwStatus);
if((pdwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
{
if(CDEmuGetStatus() == playing)
{
HRESULT result;
// Set volume of the buffer to 100%.
result = wav->GetSecondaryBuffer()->SetVolume(DSBVOLUME_MAX);
if(FAILED(result))
{
return;
}
result = wav->GetSecondaryBuffer()->Play(0, 0, DSBPLAY_LOOPING);
if(FAILED(result)) {
//
}
}
}
}
}

View File

@ -1,59 +0,0 @@
#ifndef _WavClass_H_
#define _WavClass_H_
//#include <dsound.h>
#include "dsound_core.h"
class WavClass
{
private:
struct WaveHeaderType
{
char chunkId[4];
unsigned long chunkSize;
char format[4];
char subChunkId[4];
unsigned long subChunkSize;
unsigned short audioFormat;
unsigned short numChannels;
unsigned long sampleRate;
unsigned long bytesPerSecond;
unsigned short blockAlign;
unsigned short bitsPerSample;
char dataChunkId[4];
unsigned long dataSize;
};
public:
WavClass();
WavClass(const WavClass&);
~WavClass();
bool Initialize(HWND, TCHAR*);
void Shutdown();
bool InitializeDirectSound(HWND);
void ShutdownDirectSound();
bool LoadWaveFile(TCHAR*, IDirectSoundBuffer**);
void ShutdownWaveFile(IDirectSoundBuffer**);
bool PlayWaveFile();
IDirectSound* GetDirectSound() { return m_DirectSound; }
IDirectSoundBuffer* GetPrimaryBuffer() { return m_primaryBuffer; }
IDirectSoundBuffer* GetSecondaryBuffer() { return m_secondaryBuffer1; }
private:
IDirectSound* m_DirectSound;
IDirectSoundBuffer* m_primaryBuffer;
IDirectSoundBuffer* m_secondaryBuffer1;
};
void wav_exit();
int wav_open(TCHAR* szFile);
void wav_stop();
void wav_play();
void wav_pause(bool bResume);
#endif

View File

@ -301,6 +301,23 @@
<li>Dragonball Z/Dragonball Z 2, impliment sprite dma - fixes missing/flickering sprites &amp; text, fix service mode (F2) [dink]</li>
<li>Updated Gauntlet protection, game can now progress past level 28 [iq_132]</li>
<li>Finished Carnival (Vic Dual WIP) - fix bugs / add sound [dink]</li>
<li>Neo Geo CD gets dink-style upgrade/fix/rework<ul>
<li>DAO .bin/cue and TruRip (.ccd/.sub/.img [based on Jan Klaassen's work]) support added</li>
<li>Seamless per-game savestates</li>
<li>S.S.RPG and Double Dragon works now</li>
<li>Fast loading times (even faster with F1/ffwd)</li>
<li>Dozens of bugs fixed</li>
<li>Convert your old-style Neo Geo CD .iso + .wav's to .bin/.cue, <a href="http://neo-source.com/index.php?topic=2487.msg26465#msg26465"> <b>>> click for howto <<</b> </a></li>
<li>Big thanks to Silanda and barbudreadmon for bug reports, ideas, talks and HW tests</li>
</ul></li>
<li>Added clone of Fantasy Zone to the Sega System 16A driver [Barry]</li>
<li>Sync romsets with MAME 0.206 [Barry]</li>
<li>Add Kof '98 Plus Final Edition (kof98pfe) &amp; Kof 10th Anniversary (kof10thd) hacks to Neo Geo [barbudreadmon]</li>
<li>Added driver for Incredible Technologies 32/16bit games [iq_132, dink]</li>
<li>Hook up analog dials for Pachinko Sexy Reaction 1 &amp; 2 [dink]</li>
<li>Fix crash issue with Tecmo Bowl when playing via Keyboard [dink]</li>
<li>Add RESET Line to Z80 cpu interface [dink]</li>
<li> []</li>
<li> []</li>
</ul>
<!-- new drivers -->