diff --git a/player.cpp b/player.cpp index 9965302a..e60de746 100644 --- a/player.cpp +++ b/player.cpp @@ -56,6 +56,9 @@ static const char* GetFileTitle(const char* filePath); static UINT32 FillBuffer(void* drvStruct, void* userParam, UINT32 bufSize, void* Data); static UINT8 FilePlayCallback(PlayerBase* player, void* userParam, UINT8 evtType, void* evtParam); static DATA_LOADER* RequestFileCallback(void* userParam, PlayerBase* player, const char* fileName); +static const char* LogLevel2Str(UINT8 level); +static void PlayerLogCallback(void* userParam, PlayerBase* player, UINT8 level, UINT8 srcType, + const char* srcTag, const char* message); static UINT32 GetNthAudioDriver(UINT8 adrvType, INT32 drvNumber); static UINT8 InitAudioSystem(void); static UINT8 DeinitAudioSystem(void); @@ -131,6 +134,7 @@ int main(int argc, char* argv[]) mainPlr.RegisterPlayerEngine(new GYMPlayer); mainPlr.SetEventCallback(FilePlayCallback, NULL); mainPlr.SetFileReqCallback(RequestFileCallback, NULL); + mainPlr.SetLogCallback(PlayerLogCallback, NULL); //mainPlr.SetOutputSettings() is done in StartAudioDevice() { PlayerA::Config pCfg = mainPlr.GetConfiguration(); @@ -267,7 +271,8 @@ int main(int argc, char* argv[]) if (! (retVal & 0x80)) { static const INT16 panPos[4] = {0x00, -0x80, +0x80, 0x00}; - devOpts.emuCore[0] = FCC_MAXM; + if (! devOpts.emuCore[0]) + devOpts.emuCore[0] = FCC_MAXM; memcpy(devOpts.panOpts.chnPan, panPos, sizeof(panPos)); player->SetDeviceOptions(devOptID, devOpts); } @@ -296,7 +301,8 @@ int main(int argc, char* argv[]) retVal = player->GetDeviceOptions(devOptID, devOpts); if (! (retVal & 0x80)) { - devOpts.emuCore[0] = FCC_MAME; + if (! devOpts.emuCore[0]) + devOpts.emuCore[0] = FCC_MAME; player->SetDeviceOptions(devOptID, devOpts); } } @@ -943,6 +949,26 @@ static DATA_LOADER* RequestFileCallback(void* userParam, PlayerBase* player, con return NULL; } +static const char* LogLevel2Str(UINT8 level) +{ + static const char* LVL_NAMES[6] = {" ??? ", "Error", "Warn ", "Info ", "Debug", "Trace"}; + if (level >= (sizeof(LVL_NAMES) / sizeof(LVL_NAMES[0]))) + level = 0; + return LVL_NAMES[level]; +} + +static void PlayerLogCallback(void* userParam, PlayerBase* player, UINT8 level, UINT8 srcType, + const char* srcTag, const char* message) +{ + if (level >= PLRLOG_TRACE) + return; // don't print trace logs (debug is okay) + if (srcType == PLRLOGSRC_PLR) + printf("[%s] %s: %s", LogLevel2Str(level), player->GetPlayerName(), message); + else + printf("[%s] %s %s: %s", LogLevel2Str(level), player->GetPlayerName(), srcTag, message); + return; +} + static UINT32 GetNthAudioDriver(UINT8 adrvType, INT32 drvNumber) { // special numbers for drvNumber: diff --git a/player/droplayer.cpp b/player/droplayer.cpp index 6afc78cb..07069b92 100644 --- a/player/droplayer.cpp +++ b/player/droplayer.cpp @@ -330,6 +330,7 @@ UINT8 DROPlayer::UnloadFile(void) _devPanning.clear(); _devCfgs.clear(); _devices.clear(); + _devNames.clear(); return 0x00; } @@ -591,13 +592,27 @@ UINT32 DROPlayer::GetLoopTicks(void) const return 0; } +/*static*/ void DROPlayer::SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message) +{ + DEVLOG_CB_DATA* cbData = (DEVLOG_CB_DATA*)userParam; + DROPlayer* player = cbData->player; + if (player->_logCbFunc == NULL) + return; + player->_logCbFunc(player->_logCbParam, player, level, PLRLOGSRC_EMU, + player->_devNames[cbData->chipDevID].c_str(), message); + return; +} + void DROPlayer::GenerateDeviceConfig(void) { size_t curDev; + const char* chipName; + char chipNameFull[0x10]; _devCfgs.clear(); _devCfgs.resize(_devTypes.size()); + _devNames.clear(); for (curDev = 0; curDev < _devCfgs.size(); curDev ++) { DEV_GEN_CFG* devCfg = &_devCfgs[curDev]; @@ -607,6 +622,17 @@ void DROPlayer::GenerateDeviceConfig(void) if (_devTypes[curDev] == DEVID_YMF262) devCfg->clock *= 4; // OPL3 uses a 14 MHz clock devCfg->flags = 0x00; + + chipName = (_devTypes[curDev] == DEVID_YMF262) ? "OPL3" : "OPL2"; + if (_devCfgs.size() <= 1) + { + _devNames.push_back(chipName); + } + else + { + snprintf(chipNameFull, 0x10, "%s #%u", chipName, 1 + (unsigned int)curDev); + _devNames.push_back(chipNameFull); + } } return; @@ -650,6 +676,10 @@ UINT8 DROPlayer::Start(void) } SndEmu_GetDeviceFunc(cDev->base.defInf.devDef, RWF_REGISTER | RWF_WRITE, DEVRW_A8D8, 0, (void**)&cDev->write); + cDev->logCbData.player = this; + cDev->logCbData.chipDevID = curDev; + if (cDev->base.defInf.devDef->SetLogCB != NULL) + cDev->base.defInf.devDef->SetLogCB(cDev->base.defInf.dataPtr, DROPlayer::SndEmuLogCB, &cDev->logCbData); SetupLinkedDevices(&cDev->base, NULL, NULL); if (devOpts != NULL) diff --git a/player/droplayer.hpp b/player/droplayer.hpp index 664c424d..0e452e25 100644 --- a/player/droplayer.hpp +++ b/player/droplayer.hpp @@ -70,16 +70,22 @@ struct DRO_PLAY_OPTIONS }; -typedef struct _dro_chip_device DRO_CHIPDEV; -struct _dro_chip_device -{ - VGM_BASEDEV base; - size_t optID; - DEVFUNC_WRITE_A8D8 write; -}; - class DROPlayer : public PlayerBase { +private: + struct DEVLOG_CB_DATA + { + DROPlayer* player; + size_t chipDevID; + }; + struct DRO_CHIPDEV + { + VGM_BASEDEV base; + size_t optID; + DEVFUNC_WRITE_A8D8 write; + DEVLOG_CB_DATA logCbData; + }; + public: DROPlayer(); ~DROPlayer(); @@ -131,6 +137,8 @@ class DROPlayer : public PlayerBase void ScanInitBlock(void); + static void SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message); + void GenerateDeviceConfig(void); UINT8 SeekToTick(UINT32 tick); UINT8 SeekToFilePos(UINT32 pos); @@ -167,6 +175,7 @@ class DROPlayer : public PlayerBase DRO_PLAY_OPTIONS _playOpts; PLR_DEV_OPTS _devOpts[3]; // 0 = 1st OPL2, 1 = 2nd OPL2, 2 = 1st OPL3 std::vector _devices; + std::vector _devNames; size_t _optDevMap[3]; // maps _devOpts vector index to _devices vector UINT32 _filePos; diff --git a/player/gymplayer.cpp b/player/gymplayer.cpp index 1f51a53d..6939bb8f 100644 --- a/player/gymplayer.cpp +++ b/player/gymplayer.cpp @@ -527,10 +527,22 @@ UINT32 GYMPlayer::GetLoopTicks(void) const return _totalTicks - _fileHdr.loopFrame; } +/*static*/ void GYMPlayer::SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message) +{ + DEVLOG_CB_DATA* cbData = (DEVLOG_CB_DATA*)userParam; + GYMPlayer* player = cbData->player; + if (player->_logCbFunc == NULL) + return; + player->_logCbFunc(player->_logCbParam, player, level, PLRLOGSRC_EMU, + player->_devNames[cbData->chipDevID].c_str(), message); + return; +} + void GYMPlayer::GenerateDeviceConfig(void) { _devCfgs.clear(); + _devNames.clear(); _devCfgs.resize(2); { DEV_GEN_CFG devCfg; @@ -539,6 +551,7 @@ void GYMPlayer::GenerateDeviceConfig(void) _devCfgs[0].type = DEVID_YM2612; _devCfgs[0].volume = 0x100; SaveDeviceConfig(_devCfgs[0].data, &devCfg, sizeof(DEV_GEN_CFG)); + _devNames.push_back("FM"); } { SN76496_CFG snCfg; @@ -554,6 +567,7 @@ void GYMPlayer::GenerateDeviceConfig(void) _devCfgs[1].type = DEVID_SN76496; _devCfgs[1].volume = 0x80; SaveDeviceConfig(_devCfgs[1].data, &snCfg, sizeof(SN76496_CFG)); + _devNames.push_back("PSG"); } return; @@ -597,6 +611,10 @@ UINT8 GYMPlayer::Start(void) } SndEmu_GetDeviceFunc(cDev->base.defInf.devDef, RWF_REGISTER | RWF_WRITE, DEVRW_A8D8, 0, (void**)&cDev->write); + cDev->logCbData.player = this; + cDev->logCbData.chipDevID = curDev; + if (cDev->base.defInf.devDef->SetLogCB != NULL) + cDev->base.defInf.devDef->SetLogCB(cDev->base.defInf.dataPtr, GYMPlayer::SndEmuLogCB, &cDev->logCbData); SetupLinkedDevices(&cDev->base, NULL, NULL); if (devOpts != NULL) diff --git a/player/gymplayer.hpp b/player/gymplayer.hpp index 744ff086..3e26cf7b 100644 --- a/player/gymplayer.hpp +++ b/player/gymplayer.hpp @@ -36,14 +36,6 @@ struct GYM_HEADER UINT32 realFileSize; // internal file size after possible decompression }; -typedef struct _gym_chip_device GYM_CHIPDEV; -struct _gym_chip_device -{ - VGM_BASEDEV base; - size_t optID; - DEVFUNC_WRITE_A8D8 write; -}; - class GYMPlayer : public PlayerBase { private: @@ -53,6 +45,19 @@ class GYMPlayer : public PlayerBase UINT16 volume; std::vector data; }; + struct DEVLOG_CB_DATA + { + GYMPlayer* player; + size_t chipDevID; + }; + struct GYM_CHIPDEV + { + VGM_BASEDEV base; + size_t optID; + DEVFUNC_WRITE_A8D8 write; + DEVLOG_CB_DATA logCbData; + }; + public: GYMPlayer(); ~GYMPlayer(); @@ -106,6 +111,8 @@ class GYMPlayer : public PlayerBase void LoadTag(const char* tagName, const void* data, size_t maxlen); std::string GetUTF8String(const char* startPtr, const char* endPtr); + static void SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message); + void GenerateDeviceConfig(void); UINT8 SeekToTick(UINT32 tick); UINT8 SeekToFilePos(UINT32 pos); @@ -142,6 +149,7 @@ class GYMPlayer : public PlayerBase PLR_DEV_OPTS _devOpts[2]; // 0 = YM2612, 1 = SEGA PSG std::vector _devices; + std::vector _devNames; size_t _optDevMap[2]; // maps _devOpts vector index to _devices vector UINT32 _filePos; diff --git a/player/playera.cpp b/player/playera.cpp index 3ffac207..cfe356c3 100644 --- a/player/playera.cpp +++ b/player/playera.cpp @@ -266,6 +266,13 @@ void PlayerA::SetFileReqCallback(PLAYER_FILEREQ_CB cbFunc, void* cbParam) return; } +void PlayerA::SetLogCallback(PLAYER_LOG_CB cbFunc, void* cbParam) +{ + for (size_t curPlr = 0; curPlr < _avbPlrs.size(); curPlr ++) + _avbPlrs[curPlr]->SetLogCallback(cbFunc, cbParam); + return; +} + UINT8 PlayerA::GetState(void) const { if (_player == NULL) diff --git a/player/playera.hpp b/player/playera.hpp index ec2e0c3b..4c0507e9 100644 --- a/player/playera.hpp +++ b/player/playera.hpp @@ -51,6 +51,7 @@ class PlayerA void SetEventCallback(PLAYER_EVENT_CB cbFunc, void* cbParam); void SetFileReqCallback(PLAYER_FILEREQ_CB cbFunc, void* cbParam); + void SetLogCallback(PLAYER_LOG_CB cbFunc, void* cbParam); UINT8 GetState(void) const; UINT32 GetCurPos(UINT8 unit) const; double GetCurTime(UINT8 includeLoops) const; diff --git a/player/playerbase.cpp b/player/playerbase.cpp index 7b8cf4f6..0dc6b828 100644 --- a/player/playerbase.cpp +++ b/player/playerbase.cpp @@ -8,7 +8,9 @@ PlayerBase::PlayerBase() : _eventCbFunc(NULL), _eventCbParam(NULL), _fileReqCbFunc(NULL), - _fileReqCbParam(NULL) + _fileReqCbParam(NULL), + _logCbFunc(NULL), + _logCbParam(NULL) { } @@ -83,6 +85,14 @@ void PlayerBase::SetFileReqCallback(PLAYER_FILEREQ_CB cbFunc, void* cbParam) return; } +void PlayerBase::SetLogCallback(PLAYER_LOG_CB cbFunc, void* cbParam) +{ + _logCbFunc = cbFunc; + _logCbParam = cbParam; + + return; +} + double PlayerBase::Sample2Second(UINT32 samples) const { if (samples == (UINT32)-1) diff --git a/player/playerbase.hpp b/player/playerbase.hpp index 17b6994b..d717c7de 100644 --- a/player/playerbase.hpp +++ b/player/playerbase.hpp @@ -31,6 +31,19 @@ typedef UINT8 (*PLAYER_EVENT_CB)(PlayerBase* player, void* userParam, UINT8 evtT typedef DATA_LOADER* (*PLAYER_FILEREQ_CB)(void* userParam, PlayerBase* player, const char* fileName); +typedef void (*PLAYER_LOG_CB)(void* userParam, PlayerBase* player, UINT8 level, UINT8 srcType, const char* srcTag, const char* message); +// log levels +#define PLRLOG_OFF DEVLOG_OFF +#define PLRLOG_ERROR DEVLOG_ERROR +#define PLRLOG_WARN DEVLOG_WARN +#define PLRLOG_INFO DEVLOG_INFO +#define PLRLOG_DEBUG DEVLOG_DEBUG +#define PLRLOG_TRACE DEVLOG_TRACE +// log source types +#define PLRLOGSRC_PLR 0x00 // player +#define PLRLOGSRC_EMU 0x01 // sound emulation + + struct PLR_SONG_INFO { UINT32 format; // four-character-code for file format @@ -115,6 +128,7 @@ class PlayerBase virtual UINT8 SetPlaybackSpeed(double speed); virtual void SetEventCallback(PLAYER_EVENT_CB cbFunc, void* cbParam); virtual void SetFileReqCallback(PLAYER_FILEREQ_CB cbFunc, void* cbParam); + virtual void SetLogCallback(PLAYER_LOG_CB cbFunc, void* cbParam); virtual UINT32 Tick2Sample(UINT32 ticks) const = 0; virtual UINT32 Sample2Tick(UINT32 samples) const = 0; virtual double Tick2Second(UINT32 ticks) const = 0; @@ -139,6 +153,8 @@ class PlayerBase void* _eventCbParam; PLAYER_FILEREQ_CB _fileReqCbFunc; void* _fileReqCbParam; + PLAYER_LOG_CB _logCbFunc; + void* _logCbParam; }; #endif // __PLAYERBASE_HPP__ diff --git a/player/s98player.cpp b/player/s98player.cpp index f2e01cce..d1b3f082 100644 --- a/player/s98player.cpp +++ b/player/s98player.cpp @@ -786,12 +786,24 @@ UINT32 S98Player::GetLoopTicks(void) const return _totalTicks - _loopTick; } +/*static*/ void S98Player::SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message) +{ + DEVLOG_CB_DATA* cbData = (DEVLOG_CB_DATA*)userParam; + S98Player* player = cbData->player; + if (player->_logCbFunc == NULL) + return; + player->_logCbFunc(player->_logCbParam, player, level, PLRLOGSRC_EMU, + player->_devNames[cbData->chipDevID].c_str(), message); + return; +} + void S98Player::GenerateDeviceConfig(void) { size_t curDev; _devCfgs.clear(); + _devNames.clear(); _devCfgs.resize(_devHdrs.size()); for (curDev = 0; curDev < _devCfgs.size(); curDev ++) { @@ -804,6 +816,7 @@ void S98Player::GenerateDeviceConfig(void) devCfg.flags = 0x00; deviceID = (devHdr->devType < S98DEV_END) ? S98_DEV_LIST[devHdr->devType] : 0xFF; + const char* devName = SndEmu_GetDevName(deviceID, 0x00, &devCfg); // use short name for now switch(deviceID) { case DEVID_AY8910: @@ -815,12 +828,14 @@ void S98Player::GenerateDeviceConfig(void) { ayCfg.chipType = AYTYPE_YM2149; ayCfg.chipFlags = YM2149_PIN26_LOW; + devName = "YM2149"; } else { ayCfg.chipType = AYTYPE_AY8910; ayCfg.chipFlags = 0x00; ayCfg._genCfg.clock /= 2; + devName = "AY8910"; } SaveDeviceConfig(_devCfgs[curDev].data, &ayCfg, sizeof(AY8910_CFG)); @@ -846,6 +861,16 @@ void S98Player::GenerateDeviceConfig(void) SaveDeviceConfig(_devCfgs[curDev].data, &devCfg, sizeof(DEV_GEN_CFG)); break; } + if (_devCfgs.size() <= 1) + { + _devNames.push_back(devName); + } + else + { + char fullName[0x10]; + snprintf(fullName, 0x10, "%u-%s", 1 + (unsigned int)curDev, devName); + _devNames.push_back(fullName); + } } return; @@ -921,6 +946,10 @@ UINT8 S98Player::Start(void) } SndEmu_GetDeviceFunc(cDev->base.defInf.devDef, RWF_REGISTER | RWF_WRITE, DEVRW_A8D8, 0, (void**)&cDev->write); + cDev->logCbData.player = this; + cDev->logCbData.chipDevID = curDev; + if (cDev->base.defInf.devDef->SetLogCB != NULL) + cDev->base.defInf.devDef->SetLogCB(cDev->base.defInf.dataPtr, S98Player::SndEmuLogCB, &cDev->logCbData); { DEVLINK_CB_DATA dlCbData; dlCbData.player = this; diff --git a/player/s98player.hpp b/player/s98player.hpp index 4755a868..2c338c54 100644 --- a/player/s98player.hpp +++ b/player/s98player.hpp @@ -33,15 +33,6 @@ struct S98_DEVICE UINT32 app_spec; // [v2: application-specific] [v3: reserved] }; -typedef struct _s98_chip_device S98_CHIPDEV; -struct _s98_chip_device -{ - VGM_BASEDEV base; - size_t optID; - std::vector cfg; - DEVFUNC_WRITE_A8D8 write; -}; - class S98Player : public PlayerBase { private: @@ -49,12 +40,25 @@ class S98Player : public PlayerBase { std::vector data; }; + struct DEVLOG_CB_DATA + { + S98Player* player; + size_t chipDevID; + }; + struct S98_CHIPDEV + { + VGM_BASEDEV base; + size_t optID; + std::vector cfg; + DEVFUNC_WRITE_A8D8 write; + DEVLOG_CB_DATA logCbData; + }; struct DEVLINK_CB_DATA { S98Player* player; S98_CHIPDEV* chipDev; }; - + public: S98Player(); ~S98Player(); @@ -111,6 +115,8 @@ class S98Player : public PlayerBase void RefreshTSRates(void); + static void SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message); + void GenerateDeviceConfig(void); static void DeviceLinkCallback(void* userParam, VGM_BASEDEV* cDev, DEVLINK_INFO* dLink); UINT8 SeekToTick(UINT32 tick); @@ -148,6 +154,7 @@ class S98Player : public PlayerBase PLR_DEV_OPTS _devOpts[_OPT_DEV_COUNT * 2]; // space for 2 instances per chip size_t _devOptMap[0x100][2]; // maps libvgm device ID to _devOpts vector std::vector _devices; + std::vector _devNames; size_t _optDevMap[_OPT_DEV_COUNT * 2]; // maps _devOpts vector index to _devices vector UINT32 _filePos; diff --git a/player/vgmplayer.cpp b/player/vgmplayer.cpp index c0ff03b0..84afe2c6 100644 --- a/player/vgmplayer.cpp +++ b/player/vgmplayer.cpp @@ -31,6 +31,10 @@ #include "helper.h" #include "logging.h" +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + /*static*/ const UINT8 VGMPlayer::_OPT_DEV_LIST[_OPT_DEV_COUNT] = { DEVID_SN76496, DEVID_YM2413, DEVID_YM2612, DEVID_YM2151, DEVID_SEGAPCM, DEVID_RF5C68, DEVID_YM2203, DEVID_YM2608, @@ -466,8 +470,9 @@ UINT8 VGMPlayer::UnloadFile(void) _fileData = NULL; _fileHdr.fileVer = 0xFFFFFFFF; _fileHdr.dataOfs = 0x00; - _devCfgs.clear(); + _devNames.clear(); _devices.clear(); + _devCfgs.clear(); for (size_t curTag = 0; curTag < _TAG_COUNT; curTag ++) _tagData[curTag] = std::string(); _tagList[0] = NULL; @@ -807,6 +812,17 @@ const std::vector& VGMPlayer::GetStreamDevInfo(void) con return _dacStreams; } +/*static*/ void VGMPlayer::SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message) +{ + DEVLOG_CB_DATA* cbData = (DEVLOG_CB_DATA*)userParam; + VGMPlayer* player = cbData->player; + if (player->_logCbFunc == NULL) + return; + player->_logCbFunc(player->_logCbParam, player, level, PLRLOGSRC_EMU, + player->_devNames[cbData->chipDevID].c_str(), message); + return; +} + UINT8 VGMPlayer::Start(void) { @@ -845,6 +861,7 @@ UINT8 VGMPlayer::Stop(void) for (curDev = 0; curDev < _devices.size(); curDev ++) FreeDeviceTree(&_devices[curDev].base, 0); + _devNames.clear(); _devices.clear(); _devCfgs.clear(); if (_eventCbFunc != NULL) @@ -1230,6 +1247,7 @@ void VGMPlayer::InitDevices(void) size_t curChip; _devices.clear(); + _devNames.clear(); { UINT8 vgmChip; UINT8 chipID; @@ -1431,11 +1449,24 @@ void VGMPlayer::InitDevices(void) } sdCfg.deviceID = _devices.size(); + std::string devName = SndEmu_GetDevName(chipType, 0x00, devCfg); // use short name for now + if (GetChipCount(sdCfg.vgmChipType) > 1) + { + char postFix[0x10]; + snprintf(postFix, 0x10, " #%u", 1 + chipID); + devName += postFix; + } + chipDev.logCbData.player = this; + chipDev.logCbData.chipDevID = _devices.size(); + _devNames.push_back(devName); // push here, so that we can have logs during SetupLinkedDevices() + { DEVLINK_CB_DATA dlCbData; dlCbData.player = this; dlCbData.sdCfg = &sdCfg; dlCbData.chipDev = &chipDev; + if (devInf->devDef->SetLogCB != NULL) // allow for device link warnings + devInf->devDef->SetLogCB(devInf->dataPtr, VGMPlayer::SndEmuLogCB, &chipDev.logCbData); SetupLinkedDevices(&chipDev.base, &DeviceLinkCallback, &dlCbData); } // already done by SndEmu_Start() @@ -1459,7 +1490,12 @@ void VGMPlayer::InitDevices(void) for (curChip = 0; curChip < _devices.size(); curChip ++) { CHIP_DEVICE& chipDev = _devices[curChip]; + DEV_INFO* devInf = &chipDev.base.defInf; VGM_BASEDEV* clDev; + + if (devInf->devDef->SetLogCB != NULL) + devInf->devDef->SetLogCB(devInf->dataPtr, VGMPlayer::SndEmuLogCB, &chipDev.logCbData); + UINT8 linkCntr = 0; for (clDev = &chipDev.base; clDev != NULL; clDev = clDev->linkDev, linkCntr ++) { diff --git a/player/vgmplayer.hpp b/player/vgmplayer.hpp index 8d27e7cd..ea9c051d 100644 --- a/player/vgmplayer.hpp +++ b/player/vgmplayer.hpp @@ -50,6 +50,11 @@ struct VGM_PLAY_OPTIONS class VGMPlayer : public PlayerBase { public: + struct DEVLOG_CB_DATA + { + VGMPlayer* player; + size_t chipDevID; + }; struct CHIP_DEVICE // Note: has to be a POD, because I use memset() on it. { VGM_BASEDEV base; @@ -66,6 +71,7 @@ class VGMPlayer : public PlayerBase DEVFUNC_WRITE_BLOCK romWrite; DEVFUNC_WRITE_MEMSIZE romSizeB; DEVFUNC_WRITE_BLOCK romWriteB; + DEVLOG_CB_DATA logCbData; }; struct DACSTRM_DEV { @@ -198,6 +204,8 @@ class VGMPlayer : public PlayerBase void RefreshTSRates(void); + static void SndEmuLogCB(void* userParam, void* source, UINT8 level, const char* message); + UINT32 GetHeaderChipClock(UINT8 chipType) const; // returns raw chip clock value from VGM header inline UINT32 GetChipCount(UINT8 chipType) const; UINT32 GetChipClock(UINT8 chipType, UINT8 chipID) const; @@ -208,8 +216,8 @@ class VGMPlayer : public PlayerBase void InitDevices(void); static void DeviceLinkCallback(void* userParam, VGM_BASEDEV* cDev, DEVLINK_INFO* dLink); - void LoadOPL4ROM(CHIP_DEVICE* chipDev); CHIP_DEVICE* GetDevicePtr(UINT8 chipType, UINT8 chipID); + void LoadOPL4ROM(CHIP_DEVICE* chipDev); UINT8 SeekToTick(UINT32 tick); UINT8 SeekToFilePos(UINT32 pos); @@ -340,6 +348,7 @@ class VGMPlayer : public PlayerBase size_t _vdDevMap[_CHIP_COUNT][2]; // maps VGM device ID to _devices vector size_t _optDevMap[_OPT_DEV_COUNT * 2]; // maps _devOpts vector index to _devices vector std::vector _devices; + std::vector _devNames; size_t _dacStrmMap[0x100]; // maps VGM DAC stream ID -> _dacStreams vector std::vector _dacStreams;