Merge branch 'master' of https://github.com/barry65536/FBAlpha
This commit is contained in:
commit
593201b5ed
|
@ -5,7 +5,6 @@
|
|||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <cstring>*/
|
||||
#include "burnint.h"
|
||||
#include "ide.h"
|
||||
|
||||
#define DEBUG_ATA 0
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define IDE
|
||||
|
||||
#include <string>
|
||||
#include "burnint.h"
|
||||
|
||||
namespace ide
|
||||
{
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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") };
|
|
@ -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)) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -301,6 +301,23 @@
|
|||
<li>Dragonball Z/Dragonball Z 2, impliment sprite dma - fixes missing/flickering sprites & 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) & 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 & 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 -->
|
||||
|
|
Loading…
Reference in New Issue