diff --git a/Core/BaseMapper.h b/Core/BaseMapper.h index 6c3d5cd4..12b96f0f 100644 --- a/Core/BaseMapper.h +++ b/Core/BaseMapper.h @@ -98,7 +98,7 @@ protected: virtual bool AllowRegisterRead() { return false; } virtual uint32_t GetDipSwitchCount() { return 0; } - + virtual bool HasBusConflicts() { return false; } uint8_t InternalReadRam(uint16_t addr); @@ -176,6 +176,8 @@ public: RomInfo GetRomInfo(); uint32_t GetMapperDipSwitchCount(); + virtual void ApplySamples(int16_t* buffer, size_t sampleCount, double volume) {} + uint8_t ReadRAM(uint16_t addr) override; uint8_t PeekRAM(uint16_t addr) override; uint8_t DebugReadRAM(uint16_t addr); diff --git a/Core/Console.cpp b/Core/Console.cpp index bdc67ccb..31b7a684 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -259,6 +259,8 @@ bool Console::Initialize(VirtualFile &romFile, VirtualFile &patchFile, bool forP { if(romFile.IsValid()) { Pause(); + _soundMixer->StopAudio(true); + if(!_romFilepath.empty() && _mapper) { //Ensure we save any battery file before loading a new game SaveBatteries(); @@ -273,16 +275,12 @@ bool Console::Initialize(VirtualFile &romFile, VirtualFile &patchFile, bool forP //Patch failed } } - vector fileData; - romFile.ReadFile(fileData); _batteryManager->Initialize(FolderUtilities::GetFilename(romFile.GetFileName(), false)); RomData romData; - shared_ptr mapper = MapperFactory::InitializeFromFile(shared_from_this(), romFile.GetFileName(), fileData, romData); + shared_ptr mapper = MapperFactory::InitializeFromFile(shared_from_this(), romFile, romData); if(mapper) { - _soundMixer->StopAudio(true); - bool isDifferentGame = _romFilepath != (string)romFile || _patchFilename != (string)patchFile; if(_mapper) { if(isDifferentGame) { @@ -404,6 +402,7 @@ bool Console::Initialize(VirtualFile &romFile, VirtualFile &patchFile, bool forP //Reset components before creating rewindmanager, otherwise the first save state it takes will be invalid if(!forPowerCycle) { + KeyManager::UpdateDevices(); _rewindManager.reset(new RewindManager(shared_from_this())); _notificationManager->RegisterNotificationListener(_rewindManager); } else { @@ -623,8 +622,6 @@ void Console::ResetComponents(bool softReset) _resetRunTimers = true; - KeyManager::UpdateDevices(); - //This notification MUST be sent before the UpdateInputState() below to allow MovieRecorder to grab the first frame's worth of inputs _notificationManager->SendNotification(softReset ? ConsoleNotificationType::GameReset : ConsoleNotificationType::GameLoaded); diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index bc35508c..72f47999 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -591,6 +591,7 @@ + @@ -1085,6 +1086,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index c5dcf53a..8990c5e8 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -1493,6 +1493,9 @@ Nes\Mappers\MMC + + Nes\RomLoader + @@ -1795,5 +1798,8 @@ Debugger + + Misc + \ No newline at end of file diff --git a/Core/FdsLoader.cpp b/Core/FdsLoader.cpp index a7525c0d..39575b61 100644 --- a/Core/FdsLoader.cpp +++ b/Core/FdsLoader.cpp @@ -132,10 +132,8 @@ void FdsLoader::LoadDiskData(vector& romFile, vector>& } } -RomData FdsLoader::LoadRom(vector& romFile, string filename) +void FdsLoader::LoadRom(RomData& romData, vector& romFile) { - RomData romData; - romData.Info.Hash.PrgCrc32 = CRC32::GetCRC(romFile.data(), romFile.size()); romData.Info.Format = RomFormat::Fds; @@ -148,6 +146,4 @@ RomData FdsLoader::LoadRom(vector& romFile, string filename) romData.Error = true; romData.BiosMissing = true; } - - return romData; } diff --git a/Core/FdsLoader.h b/Core/FdsLoader.h index 9e44e284..fd0987a8 100644 --- a/Core/FdsLoader.h +++ b/Core/FdsLoader.h @@ -18,5 +18,5 @@ public: vector RebuildFdsFile(vector> diskData, bool needHeader); void LoadDiskData(vector& romFile, vector> &diskData, vector> &diskHeaders); - RomData LoadRom(vector &romFile, string filename); + void LoadRom(RomData& romData, vector& romFile); }; \ No newline at end of file diff --git a/Core/INotificationListener.h b/Core/INotificationListener.h index ac673993..ab29cfe4 100644 --- a/Core/INotificationListener.h +++ b/Core/INotificationListener.h @@ -15,7 +15,7 @@ enum class ConsoleNotificationType PpuFrameDone = 9, MovieEnded = 10, ResolutionChanged = 11, - FdsBiosNotFound = 12, + BiosNotFound = 12, ConfigChanged = 13, DisconnectedFromServer = 14, PpuViewerDisplayFrame = 15, diff --git a/Core/MapperFactory.cpp b/Core/MapperFactory.cpp index 08dacf08..63238ed6 100644 --- a/Core/MapperFactory.cpp +++ b/Core/MapperFactory.cpp @@ -5,6 +5,7 @@ #include "UnifBoards.h" #include "BaseMapper.h" #include "RomData.h" +#include "VirtualFile.h" #include "A65AS.h" #include "Ac08.h" @@ -479,7 +480,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData) case 183: return new Mapper183(); case 184: return new Sunsoft184(); case 185: return new CNROM(true); - case 186: return new StudyBox(); + case 186: break; //The study box is handled as a bios file, not a iNES rom case 187: return new MMC3_187(); case 188: return new BandaiKaraoke(); case 189: return new MMC3_189(); @@ -652,6 +653,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData) case UnifBoards::Unl8237A: return new Unl8237A(); //mapper 215.1 case UnifBoards::UnlPuzzle: return new UnlPuzzle(); + case MapperFactory::StudyBoxMapperID: return new StudyBox(); case MapperFactory::NsfMapperID: return new NsfMapper(); case MapperFactory::FdsMapperID: return new FDS(); } @@ -662,12 +664,12 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData) return nullptr; } -shared_ptr MapperFactory::InitializeFromFile(shared_ptr console, string romFilename, vector &fileData, RomData &outRomData) +shared_ptr MapperFactory::InitializeFromFile(shared_ptr console, VirtualFile &romFile, RomData &romData) { RomLoader loader; - if(loader.LoadFile(romFilename, fileData)) { - RomData romData = loader.GetRomData(); + if(loader.LoadFile(romFile)) { + romData = loader.GetRomData(); if((romData.Info.IsInDatabase || romData.Info.IsNes20Header) && romData.Info.InputType != GameInputType::Unspecified) { //If in DB or a NES 2.0 file, auto-configure the inputs @@ -677,13 +679,11 @@ shared_ptr MapperFactory::InitializeFromFile(shared_ptr con } shared_ptr mapper(GetMapperFromID(romData)); - if(mapper) { - outRomData = romData; return mapper; } } else if(loader.GetRomData().BiosMissing) { - console->GetNotificationManager()->SendNotification(ConsoleNotificationType::FdsBiosNotFound); + console->GetNotificationManager()->SendNotification(ConsoleNotificationType::BiosNotFound, (void*)loader.GetRomData().Info.Format); } return nullptr; } diff --git a/Core/MapperFactory.h b/Core/MapperFactory.h index f33f44ee..3cdbb10c 100644 --- a/Core/MapperFactory.h +++ b/Core/MapperFactory.h @@ -4,6 +4,7 @@ class MemoryManager; class Console; class BaseMapper; +class VirtualFile; struct RomData; class MapperFactory @@ -14,6 +15,7 @@ class MapperFactory public: static constexpr uint16_t FdsMapperID = 65535; static constexpr uint16_t NsfMapperID = 65534; + static constexpr uint16_t StudyBoxMapperID = 65533; - static shared_ptr InitializeFromFile(shared_ptr console, string romFilename, vector &fileData, RomData &outRomData); + static shared_ptr InitializeFromFile(shared_ptr console, VirtualFile &romFile, RomData &outRomData); }; diff --git a/Core/NsfLoader.cpp b/Core/NsfLoader.cpp index 1a91185a..021e36a5 100644 --- a/Core/NsfLoader.cpp +++ b/Core/NsfLoader.cpp @@ -116,9 +116,8 @@ void NsfLoader::InitHeader(NsfHeader & header) } } -RomData NsfLoader::LoadRom(vector& romFile) +void NsfLoader::LoadRom(RomData& romData, vector& romFile) { - RomData romData; NsfHeader &header = romData.Info.NsfInfo; InitHeader(header); @@ -167,6 +166,4 @@ RomData NsfLoader::LoadRom(vector& romFile) romData.Info.FilePrgOffset = 0x80; InitializeFromHeader(romData); - - return romData; } diff --git a/Core/NsfLoader.h b/Core/NsfLoader.h index 3fed453f..556b3585 100644 --- a/Core/NsfLoader.h +++ b/Core/NsfLoader.h @@ -19,5 +19,5 @@ protected: public: using BaseLoader::BaseLoader; - RomData LoadRom(vector& romFile); + void LoadRom(RomData& romData, vector& romFile); }; \ No newline at end of file diff --git a/Core/NsfeLoader.h b/Core/NsfeLoader.h index 0c3727bf..03582aa9 100644 --- a/Core/NsfeLoader.h +++ b/Core/NsfeLoader.h @@ -181,9 +181,8 @@ private: public: using NsfLoader::NsfLoader; - RomData LoadRom(vector& romFile) + void LoadRom(RomData& romData, vector& romFile) { - RomData romData; NsfHeader &header = romData.Info.NsfInfo; InitHeader(header); @@ -205,7 +204,5 @@ public: } InitializeFromHeader(romData); - - return romData; } }; \ No newline at end of file diff --git a/Core/RomData.h b/Core/RomData.h index aa01530c..c82b1617 100644 --- a/Core/RomData.h +++ b/Core/RomData.h @@ -92,6 +92,19 @@ struct RomInfo GameInfo DatabaseInfo; }; +struct PageInfo +{ + uint32_t AudioOffset; + vector Data; +}; + +struct StudyBoxData +{ + string FileName; + vector AudioFile; + vector Pages; +}; + struct RomData { RomInfo Info; @@ -106,10 +119,10 @@ struct RomData vector TrainerData; vector> FdsDiskData; vector> FdsDiskHeaders; + StudyBoxData StudyBox; vector RawData; bool Error = false; bool BiosMissing = false; - }; diff --git a/Core/RomLoader.cpp b/Core/RomLoader.cpp index a5b04380..9da92233 100644 --- a/Core/RomLoader.cpp +++ b/Core/RomLoader.cpp @@ -12,29 +12,27 @@ #include "NsfLoader.h" #include "NsfeLoader.h" #include "UnifLoader.h" +#include "StudyBoxLoader.h" -bool RomLoader::LoadFile(VirtualFile romFile) +bool RomLoader::LoadFile(VirtualFile &romFile) { - vector fileData; - if(romFile.IsValid()) { - romFile.ReadFile(fileData); - return LoadFile(romFile.GetFileName(), fileData); - } else { + if(!romFile.IsValid()) { return false; } -} -bool RomLoader::LoadFile(string filename, vector &fileData) -{ + vector& fileData = _romData.RawData; + romFile.ReadFile(fileData); if(fileData.size() < 15) { return false; } - _filename = filename; - - string romName = FolderUtilities::GetFilename(filename, true); + _filename = romFile.GetFileName(); + string romName = FolderUtilities::GetFilename(_filename, true); + bool skipSha1Hash = false; uint32_t crc = CRC32::GetCRC(fileData.data(), fileData.size()); + _romData.Info.Hash.Crc32 = crc; + Log(""); Log("Loading rom: " + romName); stringstream crcHex; @@ -43,25 +41,29 @@ bool RomLoader::LoadFile(string filename, vector &fileData) if(memcmp(fileData.data(), "NES\x1a", 4) == 0) { iNesLoader loader(_checkOnly); - _romData = loader.LoadRom(fileData, nullptr); + loader.LoadRom(_romData, fileData, nullptr); } else if(memcmp(fileData.data(), "FDS\x1a", 4) == 0 || memcmp(fileData.data(), "\x1*NINTENDO-HVC*", 15) == 0) { FdsLoader loader(_checkOnly); - _romData = loader.LoadRom(fileData, _filename); + loader.LoadRom(_romData, fileData); } else if(memcmp(fileData.data(), "NESM\x1a", 5) == 0) { NsfLoader loader(_checkOnly); - _romData = loader.LoadRom(fileData); + loader.LoadRom(_romData, fileData); } else if(memcmp(fileData.data(), "NSFE", 4) == 0) { NsfeLoader loader(_checkOnly); - _romData = loader.LoadRom(fileData); + loader.LoadRom(_romData, fileData); } else if(memcmp(fileData.data(), "UNIF", 4) == 0) { UnifLoader loader(_checkOnly); - _romData = loader.LoadRom(fileData); + loader.LoadRom(_romData, fileData); + } else if(memcmp(fileData.data(), "STBX", 4) == 0) { + StudyBoxLoader loader(_checkOnly); + loader.LoadRom(_romData, fileData, romFile.GetFilePath()); + skipSha1Hash = true; } else { NESHeader header = {}; if(GameDatabase::GetiNesHeader(crc, header)) { Log("[DB] Headerless ROM file found - using game database data."); iNesLoader loader; - _romData = loader.LoadRom(fileData, &header); + loader.LoadRom(_romData, fileData, &header); _romData.Info.IsHeaderlessRom = true; } else { Log("Invalid rom file."); @@ -69,9 +71,10 @@ bool RomLoader::LoadFile(string filename, vector &fileData) } } - _romData.Info.Hash.Crc32 = crc; - _romData.Info.Hash.Sha1 = SHA1::GetHash(fileData); - _romData.RawData = fileData; + if(!skipSha1Hash) { + _romData.Info.Hash.Sha1 = SHA1::GetHash(fileData); + } + _romData.Info.RomName = romName; _romData.Info.Filename = _filename; @@ -105,9 +108,10 @@ string RomLoader::FindMatchingRomInFile(string filePath, HashInfo hashInfo, int for(string file : reader->GetFileList(VirtualFile::RomExtensions)) { RomLoader loader(true); vector fileData; - if(loader.LoadFile(filePath)) { + VirtualFile innerFile(filePath, file); + if(loader.LoadFile(innerFile)) { if(hashInfo.Crc32 == loader._romData.Info.Hash.Crc32 || hashInfo.Sha1.compare(loader._romData.Info.Hash.Sha1) == 0) { - return VirtualFile(filePath, file); + return innerFile; } iterationCount++; @@ -118,8 +122,8 @@ string RomLoader::FindMatchingRomInFile(string filePath, HashInfo hashInfo, int } } else { RomLoader loader(true); - vector fileData; - if(loader.LoadFile(filePath)) { + VirtualFile file = filePath; + if(loader.LoadFile(file)) { if(hashInfo.Crc32 == loader._romData.Info.Hash.Crc32 || hashInfo.Sha1.compare(loader._romData.Info.Hash.Sha1) == 0) { return filePath; } diff --git a/Core/RomLoader.h b/Core/RomLoader.h index f3ca7f5e..0afbad74 100644 --- a/Core/RomLoader.h +++ b/Core/RomLoader.h @@ -18,8 +18,7 @@ private: public: using BaseLoader::BaseLoader; - bool LoadFile(VirtualFile romFile); - bool LoadFile(string filename, vector &fileData); + bool LoadFile(VirtualFile &romFile); RomData GetRomData(); static string FindMatchingRom(vector romFiles, string romFilename, HashInfo hashInfo, bool useFastSearch); diff --git a/Core/SoundMixer.cpp b/Core/SoundMixer.cpp index ea6b3f65..59ffcf15 100644 --- a/Core/SoundMixer.cpp +++ b/Core/SoundMixer.cpp @@ -8,6 +8,7 @@ #include "WaveRecorder.h" #include "OggMixer.h" #include "Console.h" +#include "BaseMapper.h" SoundMixer::SoundMixer(shared_ptr console) { @@ -116,6 +117,8 @@ void SoundMixer::PlayAudioBuffer(uint32_t time) } } + _console->GetMapper()->ApplySamples(_outputBuffer, sampleCount, _settings->GetMasterVolume()); + if(_oggMixer) { _oggMixer->ApplySamples(_outputBuffer, sampleCount, _settings->GetMasterVolume()); } diff --git a/Core/StudyBox.h b/Core/StudyBox.h index a68c254f..df2cac12 100644 --- a/Core/StudyBox.h +++ b/Core/StudyBox.h @@ -2,13 +2,17 @@ #include "stdafx.h" #include "BaseMapper.h" #include "MemoryManager.h" -#include "VirtualFile.h" +#include "Console.h" +#include "../Utilities/WavReader.h" #include "../Utilities/FolderUtilities.h" +#include "../Utilities/StringUtilities.h" #include "../Utilities/HexUtilities.h" class StudyBox : public BaseMapper { private: + shared_ptr _wavReader; + bool _readyForBit = false; uint16_t _processBitDelay = 0; uint8_t _reg4202 = 0; @@ -22,12 +26,14 @@ private: bool _enableDecoder = false; + bool _audioEnabled = false; bool _motorDisabled = false; uint16_t _byteReadDelay = 0; bool _irqEnabled = false; bool _pageFound = false; - vector _pageData; + StudyBoxData _tapeData; + int32_t _pageIndex = 0; int32_t _pagePosition = -1; uint32_t _inDataDelay = 0; @@ -56,9 +62,28 @@ protected: SetMirroringType(MirroringType::FourScreens); } + void InitMapper(RomData& romData) override + { + _tapeData = romData.StudyBox; + _wavReader = WavReader::Create(_tapeData.AudioFile.data(), (uint32_t)_tapeData.AudioFile.size()); + if(!_wavReader) { + MessageManager::Log("[Study Box] Unsupported audio file format."); + } + } + void StreamState(bool saving) override { BaseMapper::StreamState(saving); + int32_t audioPosition = _wavReader ? _wavReader->GetPosition() : -1; + Stream( + _readyForBit, _processBitDelay, _reg4202, _commandCounter, _command, _currentPage, _seekPage, _seekPageDelay, _enableDecoder, + _audioEnabled, _motorDisabled, _byteReadDelay, _irqEnabled, _pageFound, _pageIndex, _pagePosition, _inDataDelay, _inDataRegion, audioPosition + ); + + if(!saving && audioPosition >= 0 && _wavReader) { + _wavReader->SetSampleRate(_console->GetSettings()->GetSampleRate()); + _wavReader->Play(audioPosition); + } } void ProcessCpuClock() override @@ -70,47 +95,55 @@ protected: } } - if(_seekPage != 0) { + if(_motorDisabled) { + return; + } + + if(_seekPage != _currentPage) { _seekPageDelay--; if(_seekPageDelay == 0) { _seekPageDelay = 3000000; _pageFound = true; - if(_seekPage > 0) { + if(_seekPage > _currentPage) { _currentPage++; - _seekPage--; } else { _currentPage--; - _seekPage++; } - VirtualFile file(FolderUtilities::CombinePath("StudyBox", "Page" + std::to_string(_currentPage) + ".bin")); - file.ReadFile(_pageData); - + _pageIndex = 0; + for(size_t i = 0; i < _tapeData.Pages.size(); i++) { + if(_tapeData.Pages[i].Data[5] == _currentPage - 1) { + //Find the first page that matches the requested page number + _pageIndex = (int32_t)i; + break; + } + } + _inDataDelay = 300000; _pagePosition = -1; _byteReadDelay = 0; } - } - - if(_inDataDelay > 0) { + } else if(_inDataDelay > 0) { _inDataRegion = true; _inDataDelay--; if(_inDataDelay == 0) { _byteReadDelay = 7820; + if(_wavReader) { + _wavReader->SetSampleRate(_console->GetSettings()->GetSampleRate()); + _wavReader->Play(_tapeData.Pages[_pageIndex].AudioOffset); + } _console->GetCpu()->SetIrqSource(IRQSource::External); } - } - - if(!_motorDisabled && _byteReadDelay > 0) { + } else if(_byteReadDelay > 0) { _byteReadDelay--; if(_byteReadDelay == 0) { _byteReadDelay = 3355; _pagePosition++; - if(_pagePosition >= (int32_t)_pageData.size()) { + if(_pagePosition >= (int32_t)_tapeData.Pages[_pageIndex].Data.size()) { _pageFound = false; _inDataRegion = false; - //_motorDisabled = true; + _motorDisabled = true; } if(_irqEnabled) { @@ -129,11 +162,13 @@ protected: } _console->GetCpu()->ClearIrqSource(IRQSource::External); - if(_pagePosition >= 0 && _pagePosition < (int32_t)_pageData.size()) { - //MessageManager::Log("Read: " + HexUtilities::ToHex(_pageData[_pagePosition])); - return _pageData[_pagePosition]; + if(_pagePosition >= 0 && _pagePosition < (int32_t)_tapeData.Pages[_pageIndex].Data.size()) { + //MessageManager::Log("Read: " + HexUtilities::ToHex(_tapeData.Pages[_pageIndex].Data[_pagePosition])); + return _tapeData.Pages[_pageIndex].Data[_pagePosition]; } - return 0; + + //After command $86, games expect to read 1 $AA byte before the $C5 header + return 0xAA; } case 0x4201: { @@ -207,34 +242,35 @@ protected: if(_commandCounter == 8) { _commandCounter = 0; - MessageManager::Log("Command sent: " + std::to_string(_command)); + //MessageManager::Log("Command sent: " + std::to_string(_command)); if(_command >= 1 && _command < 0x40) { - _seekPage = _command; + _seekPage = _command + _currentPage; _seekPageDelay = 3000000; _motorDisabled = false; } else if(_command > 0x40 && _command < 0x80) { - _seekPage = -(_command - 0x40); + _seekPage = -(_command - 0x40) + _currentPage; _seekPageDelay = 3000000; _motorDisabled = false; } else if(_command == 0) { - _seekPage = -1; + _seekPage = _currentPage; + _currentPage = _currentPage - 1; _seekPageDelay = 3000000; _motorDisabled = false; } else if(_command == 0x86) { - while(_pagePosition < (int32_t)_pageData.size() && _pageData[_pagePosition] != 0xC5) { - _pagePosition++; + if(_pageIndex < (int32_t)_tapeData.Pages.size() - 1 && _tapeData.Pages[_pageIndex + 1].Data[5] == _currentPage - 1) { + _pageIndex++; + _pagePosition = -1; + } else { + _pagePosition = (int32_t)_tapeData.Pages[_pageIndex + 1].Data.size(); } - _pagePosition--; _inDataDelay = 300000; _motorDisabled = false; _byteReadDelay = 0; _pageFound = true; + } else { + MessageManager::Log("Unknown command sent: " + std::to_string(_command)); } - - /*} else if(_command == 0xFF) { - //??? - }*/ } } @@ -243,9 +279,9 @@ protected: _processBitDelay = 100; } - if((_reg4202 & 0x6E) != (value & 0x6E)) { + /*if((_reg4202 & 0x6E) != (value & 0x6E)) { MessageManager::Log("Reg 4202 value changed: " + HexUtilities::ToHex(_reg4202) + " -> " + HexUtilities::ToHex(value)); - } + }*/ if((_reg4202 & 0x20) && !(value & 0x20)) { //Reset drive @@ -255,20 +291,18 @@ protected: } if((value & 0x04) != (_reg4202 & 0x04)) { - MessageManager::Log((value & 0x04) ? "Audio disabled" : "Audio enabled"); + _audioEnabled = (value & 0x04) == 0; + //MessageManager::Log(_audioEnabled ? "Audio enabled" : "Audio disabled"); } if((value & 0x02) != (_reg4202 & 0x02)) { - MessageManager::Log((value & 0x02) ? "IRQ enabled" : "IRQ disabled"); + //MessageManager::Log((value & 0x02) ? "IRQ enabled" : "IRQ disabled"); } /*if((value & 0x01) != (_reg4202 & 0x01)) { MessageManager::Log((value & 0x01) ? "Decoder enabled" : "Decoder disabled"); }*/ - if(!(_reg4202 & 0x04) && (value & 0x04)) { - _motorDisabled = true; - } _reg4202 = value; _enableDecoder = value & 0x01; _irqEnabled = value & 0x02; @@ -280,4 +314,12 @@ protected: break; } } + +public: + void ApplySamples(int16_t* buffer, size_t sampleCount, double volume) override + { + if(!_motorDisabled && _wavReader) { + _wavReader->ApplySamples(buffer, sampleCount, _audioEnabled ? volume : 0); + } + } }; \ No newline at end of file diff --git a/Core/StudyBoxLoader.cpp b/Core/StudyBoxLoader.cpp new file mode 100644 index 00000000..d91498c7 --- /dev/null +++ b/Core/StudyBoxLoader.cpp @@ -0,0 +1,141 @@ +#include "stdafx.h" +#include "StudyBoxLoader.h" +#include "RomData.h" +#include "MapperFactory.h" +#include "../Utilities/FolderUtilities.h" +#include "../Utilities/HexUtilities.h" + +uint32_t StudyBoxLoader::ReadInt(uint8_t*& data) +{ + uint32_t val = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + data += 4; + return val; +} + +string StudyBoxLoader::ReadFourCC(uint8_t*& data) +{ + stringstream ss; + for(int i = 0; i < 4; i++) { + ss << (char)data[i]; + } + data += 4; + return ss.str(); +} + +vector StudyBoxLoader::ReadArray(uint8_t*& data, uint32_t length) +{ + vector out; + out.resize(length); + memcpy(out.data(), data, length); + data += length; + return out; +} + +bool StudyBoxLoader::LoadStudyBoxTape(vector studyBoxFile, StudyBoxData& studyBoxData) +{ + uint8_t* data = studyBoxFile.data(); + uint8_t* end = data + studyBoxFile.size(); + + if(end - data < 16) { + //File too small to parse + Log("[Study Box] File is too small to parse"); + return false; + } + + if(ReadFourCC(data) != "STBX") { + //Invalid file! + Log("[Study Box] Invalid studybox file"); + return false; + } + + uint32_t size = ReadInt(data); + if(size != 4) { + //Should be 4 bytes, with only a version field + Log("[Study Box] Unexpected length value"); + return false; + } + + uint32_t version = ReadInt(data); + if(version != 0x100) { + //Unsupported version + Log("[Study Box] Unsupported version: " + std::to_string(version)); + return false; + } + + uint32_t prevAudioOffset = 0; + while(data < end - 4) { + string cc = ReadFourCC(data); + + if(cc == "PAGE") { + uint32_t pageSize = ReadInt(data); + uint32_t audioOffset = ReadInt(data); + if(audioOffset < prevAudioOffset) { + //Invalid file, page chunks must be in the order found on the tape + Log("[Study Box] PAGE chunks must be in the order found on the audio tape"); + return false; + } + + if((end - data) >= pageSize - 4) { + vector pageData = ReadArray(data, pageSize - 4); + studyBoxData.Pages.push_back({ audioOffset, pageData }); + } else { + //Invalid size value + Log("[Study Box] Invalid size value for PAGE chunk"); + return false; + } + } else if(cc == "AUDI") { + uint32_t size = ReadInt(data); + uint32_t fileType = ReadInt(data); + if(fileType == 0) { + studyBoxData.AudioFile = ReadArray(data, size); + //AUDI chunk should be the last in the file + break; + } else { + //Unsupported audio type + Log("[Study Box] Unsupported audio type: " + std::to_string(fileType)); + return false; + } + } else { + //Unsupported tag + Log("[Study Box] Unsupported tag"); + return false; + } + } + + return studyBoxData.Pages.size() > 0; +} + +vector StudyBoxLoader::LoadBios() +{ + vector biosData; + ifstream biosFile(FolderUtilities::CombinePath(FolderUtilities::GetHomeFolder(), "StudyBox.bin"), ios::in | ios::binary); + if(biosFile) { + return vector(std::istreambuf_iterator(biosFile), {}); + } + return {}; +} + +void StudyBoxLoader::LoadRom(RomData& romData, vector& romFile, string filepath) +{ + romData.Info.Hash.PrgCrc32 = romData.Info.Hash.Crc32; + + //Cheat for SHA1 hash (repeat crc32 5 times) - this is to avoid the performance penalty of running SHA1 on a large file + string crc32String = HexUtilities::ToHex(romData.Info.Hash.Crc32); + romData.Info.Hash.Sha1 = crc32String + crc32String + crc32String + crc32String + crc32String; + + romData.Info.Format = RomFormat::StudyBox; + romData.Info.MapperID = MapperFactory::StudyBoxMapperID; + romData.Info.Mirroring = MirroringType::Vertical; + romData.PrgRom = LoadBios(); + romData.Info.System = GameSystem::Famicom; + + if(romData.PrgRom.size() != 0x40000) { + romData.Error = true; + romData.BiosMissing = true; + } else { + romData.StudyBox.FileName = filepath; + if(!LoadStudyBoxTape(romFile, romData.StudyBox)) { + romData.Error = true; + } + } +} diff --git a/Core/StudyBoxLoader.h b/Core/StudyBoxLoader.h new file mode 100644 index 00000000..dba2456a --- /dev/null +++ b/Core/StudyBoxLoader.h @@ -0,0 +1,22 @@ +#pragma once +#include "stdafx.h" +#include "BaseLoader.h" + +struct StudyBoxData; +struct RomData; + +class StudyBoxLoader : public BaseLoader +{ +private: + uint32_t ReadInt(uint8_t*& data); + string ReadFourCC(uint8_t*& data); + vector ReadArray(uint8_t*& data, uint32_t length); + + bool LoadStudyBoxTape(vector studyBoxFile, StudyBoxData& studyBoxData); + vector LoadBios(); + +public: + using BaseLoader::BaseLoader; + + void LoadRom(RomData& romData, vector& romFile, string filepath); +}; \ No newline at end of file diff --git a/Core/Types.h b/Core/Types.h index bff8ebb0..999b3714 100644 --- a/Core/Types.h +++ b/Core/Types.h @@ -360,6 +360,7 @@ enum class RomFormat Unif = 2, Fds = 3, Nsf = 4, + StudyBox = 5 }; enum class VsSystemType diff --git a/Core/UnifLoader.h b/Core/UnifLoader.h index 06881984..9ca74405 100644 --- a/Core/UnifLoader.h +++ b/Core/UnifLoader.h @@ -160,10 +160,8 @@ public: return UnifBoards::UnknownBoard; } - RomData LoadRom(vector& romFile) + void LoadRom(RomData &romData, vector& romFile) { - RomData romData; - //Skip header, version & null bytes, start reading at first chunk uint8_t* data = romFile.data() + 32; uint8_t* endOfFile = romFile.data() + romFile.size(); @@ -220,7 +218,5 @@ public: romData.Error = true; } } - - return romData; } }; \ No newline at end of file diff --git a/Core/VirtualFile.cpp b/Core/VirtualFile.cpp index faa3eca1..9d22903a 100644 --- a/Core/VirtualFile.cpp +++ b/Core/VirtualFile.cpp @@ -10,7 +10,7 @@ #include "../Utilities/IpsPatcher.h" #include "../Utilities/UpsPatcher.h" -const std::initializer_list VirtualFile::RomExtensions = { ".nes", ".fds", ".nsf", ".nsfe", "*.unf", "*.unif" }; +const std::initializer_list VirtualFile::RomExtensions = { ".nes", ".fds", ".nsf", ".nsfe", ".unf", ".unif", ".studybox" }; VirtualFile::VirtualFile() { @@ -97,8 +97,29 @@ void VirtualFile::LoadFile() bool VirtualFile::IsValid() { - LoadFile(); - return _data.size() > 0; + if(_data.size() > 0) { + return true; + } + + if(!_innerFile.empty()) { + shared_ptr reader = ArchiveReader::GetReader(_path); + if(reader) { + vector filelist = reader->GetFileList(VirtualFile::RomExtensions); + if(_innerFileIndex >= 0) { + if((int32_t)filelist.size() > _innerFileIndex) { + return true; + } + } else { + return std::find(filelist.begin(), filelist.end(), _innerFile) != filelist.end(); + } + } + } else { + ifstream input(_path, std::ios::in | std::ios::binary); + if(input) { + return true; + } + } + return false; } string VirtualFile::GetFilePath() diff --git a/Core/iNesLoader.cpp b/Core/iNesLoader.cpp index 3e800f0c..86c9fd63 100644 --- a/Core/iNesLoader.cpp +++ b/Core/iNesLoader.cpp @@ -6,10 +6,8 @@ #include "GameDatabase.h" #include "EmulationSettings.h" -RomData iNesLoader::LoadRom(vector& romFile, NESHeader *preloadedHeader) +void iNesLoader::LoadRom(RomData& romData, vector& romFile, NESHeader *preloadedHeader) { - RomData romData; - NESHeader header; uint8_t* buffer = romFile.data(); uint32_t dataSize = (uint32_t)romFile.size(); @@ -52,7 +50,7 @@ RomData iNesLoader::LoadRom(vector& romFile, NESHeader *preloadedHeader } else { romData.Error = true; MessageManager::Log("[iNes] Invalid file (file length does not match header information) - load operation cancelled."); - return romData; + return; } } @@ -75,7 +73,7 @@ RomData iNesLoader::LoadRom(vector& romFile, NESHeader *preloadedHeader //Invalid rom file MessageManager::Log("[iNes] Invalid file (file length does not match header information) - load operation cancelled."); romData.Error = true; - return romData; + return; } else if(prgSize + chrSize < dataSize) { MessageManager::Log("[iNes] Warning: File is larger than excepted (based on the file header)."); } @@ -131,6 +129,4 @@ RomData iNesLoader::LoadRom(vector& romFile, NESHeader *preloadedHeader if(!_checkOnly) { GameDatabase::SetGameInfo(romData.Info.Hash.PrgChrCrc32, romData, GameDatabase::IsEnabled() && header.GetRomHeaderVersion() != RomHeaderVersion::Nes2_0, preloadedHeader != nullptr); } - - return romData; } diff --git a/Core/iNesLoader.h b/Core/iNesLoader.h index 89421b99..485e5fad 100644 --- a/Core/iNesLoader.h +++ b/Core/iNesLoader.h @@ -8,5 +8,5 @@ class iNesLoader : public BaseLoader public: using BaseLoader::BaseLoader; - RomData LoadRom(vector& romFile, NESHeader *preloadedHeader); + void LoadRom(RomData& romData, vector& romFile, NESHeader *preloadedHeader); }; \ No newline at end of file diff --git a/GUI.NET/BiosHelper.cs b/GUI.NET/BiosHelper.cs new file mode 100644 index 00000000..7aaaaaa3 --- /dev/null +++ b/GUI.NET/BiosHelper.cs @@ -0,0 +1,71 @@ +using Mesen.GUI.Config; +using Mesen.GUI.Forms; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Mesen.GUI +{ + public static class BiosHelper + { + private static string GetFileHash(string filename, out byte[] fileData) + { + using(SHA256 sha256Hash = SHA256.Create()) { + // ComputeHash - returns byte array + byte[] data = File.ReadAllBytes(filename); + if(data[0] == 'N' && data[1] == 'E' && data[2] == 'S' && data[3] == '\x1a') { + //Ignore iNES header if one exists at the start of the file + byte[] dataWithoutHeader = new byte[data.Length - 16]; + Array.Copy(data, 16, dataWithoutHeader, 0, dataWithoutHeader.Length); + data = dataWithoutHeader; + } + fileData = data; + + byte[] bytes = sha256Hash.ComputeHash(data); + + // Convert byte array to a string + StringBuilder builder = new StringBuilder(); + for(int i = 0; i < bytes.Length; i++) { + builder.Append(bytes[i].ToString("X2")); + } + return builder.ToString(); + } + } + + private static List GetExpectedHashes(RomFormat format) + { + switch(format) { + case RomFormat.Fds: return new List { "99C18490ED9002D9C6D999B9D8D15BE5C051BDFA7CC7E73318053C9A994B0178", "A0A9D57CBACE21BF9C85C2B85E86656317F0768D7772ACC90C7411AB1DBFF2BF" }; + case RomFormat.StudyBox: return new List { "365F84C86F7F7C3AAA2042D78494D41448E998EC5A89AC1B5FECB452951D514C" }; + } + throw new Exception("Unexpected format type"); + } + + public static bool RequestBiosFile(string fileName, int fileSize, RomFormat format) + { + if(MesenMsgBox.Show("BiosNotFound", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, fileName, fileSize.ToString()) == DialogResult.OK) { + using(OpenFileDialog ofd = new OpenFileDialog()) { + ofd.SetFilter(ResourceHelper.GetMessage("FilterAll")); + if(ofd.ShowDialog(Application.OpenForms[0]) == DialogResult.OK) { + byte[] fileData; + string hash = GetFileHash(ofd.FileName, out fileData); + if(!GetExpectedHashes(format).Contains(hash)) { + if(MesenMsgBox.Show("BiosMismatch", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, GetExpectedHashes(format)[0], hash) != DialogResult.OK) { + //Files don't match and user cancelled the action + return false; + } + } + File.WriteAllBytes(Path.Combine(ConfigManager.HomeFolder, fileName), fileData); + return true; + } + } + } + return false; + } + } +} diff --git a/GUI.NET/Controls/ctrlRecentGame.cs b/GUI.NET/Controls/ctrlRecentGame.cs index ea299c4a..af83ee5f 100644 --- a/GUI.NET/Controls/ctrlRecentGame.cs +++ b/GUI.NET/Controls/ctrlRecentGame.cs @@ -10,11 +10,13 @@ using System.Windows.Forms; using System.IO; using System.IO.Compression; using Mesen.GUI.Config; +using static Mesen.GUI.Controls.ctrlRecentGames; namespace Mesen.GUI.Controls { public partial class ctrlRecentGame : UserControl { + public event RecentGameLoadedHandler OnRecentGameLoaded; private RecentGameInfo _recentGame; public ctrlRecentGame() @@ -75,7 +77,7 @@ namespace Mesen.GUI.Controls private void picPreviousState_Click(object sender, EventArgs e) { InteropEmu.LoadRecentGame(_recentGame.FileName, ConfigManager.Config.PreferenceInfo.GameSelectionScreenResetGame); - //OnRecentGameLoaded?.Invoke(_recentGame); + OnRecentGameLoaded?.Invoke(_recentGame); } } } diff --git a/GUI.NET/Controls/ctrlRecentGames.cs b/GUI.NET/Controls/ctrlRecentGames.cs index 2411924d..aac51237 100644 --- a/GUI.NET/Controls/ctrlRecentGames.cs +++ b/GUI.NET/Controls/ctrlRecentGames.cs @@ -91,6 +91,7 @@ namespace Mesen.GUI.Controls for(int j = 0; j < _elementsPerRow; j++) { for(int i = 0; i < _elementsPerRow; i++) { ctrlRecentGame ctrl = new ctrlRecentGame(); + ctrl.OnRecentGameLoaded += RecentGameLoaded; ctrl.Dock = DockStyle.Fill; ctrl.Margin = new Padding(2); tlpGrid.Controls.Add(ctrl, i, j); @@ -241,6 +242,11 @@ namespace Mesen.GUI.Controls OnRecentGameLoaded?.Invoke(_recentGames[_currentIndex]); } + private void RecentGameLoaded(RecentGameInfo gameInfo) + { + OnRecentGameLoaded?.Invoke(gameInfo); + } + private bool _waitForRelease = false; private void tmrInput_Tick(object sender, EventArgs e) { diff --git a/GUI.NET/Dependencies/resources.ca.xml b/GUI.NET/Dependencies/resources.ca.xml index c9342d9e..fd880fd0 100644 --- a/GUI.NET/Dependencies/resources.ca.xml +++ b/GUI.NET/Dependencies/resources.ca.xml @@ -757,8 +757,8 @@ Fitxers de so (*.wav)|*.wav|Tots els fitxers(*.*)|*.* Fitxers de vídeo (*.avi)|*.avi|Tots els fitxers (*.*)|*.* Fitxers de paleta (*.pal)|*.pal|Tots els fitxers (*.*)|*.* - Tots els formats suportats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Fitxers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arxius comprimits (*.zip)|*.ZIP|Arxius 7-Zip (*.7z)|*.7z|Tots els fitxers (*.*)|*.* - Tots els formats suportats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES(*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Fitxers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arxius comprimits (*.zip)|*.ZIP|Arxius 7-Zip (*.7z)|*.7z|Pedaços IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Tots els fitxers (*.*)|*.* + Tots els formats suportats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Fitxers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arxius comprimits (*.zip)|*.ZIP|Arxius 7-Zip (*.7z)|*.7z|Tots els fitxers (*.*)|*.* + Tots els formats suportats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES(*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Fitxers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arxius comprimits (*.zip)|*.ZIP|Arxius 7-Zip (*.7z)|*.7z|Pedaços IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Tots els fitxers (*.*)|*.* Fitxers de proves (*.mtp)|*.mtp|Tots els fitxers (*.*)|*.* Tots els formats suportats (*.cht, *.xml)|*.cht;*.xml Partides guardades de Mesen (*.mst)|*.mst|Tots els fitxers (*.*)|*.* @@ -818,11 +818,11 @@ <No hi ha còpia de seguretat> S'ha produït un error durant la cerca d'actualitzacions. Comproveu la vostra connexió a la xarxa i proveu-ho de nou. Detalls de l'error: {0} Les actualitzacions automàtiques no estan activades en aquesta compilació - si us plau, descarregueu-vos la darrera versió del codi font i torneu a compilar Mesen per a obtenir les darreres actualitzacions. - No s'ha trobat una bios necessària per a poder jugar a jocs de la FDS. Voleu seleccionar-ne una manualment? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? Disc {0} Cara {1} Fitxer no trobat: {0} - La bios seleccionada no és vàlida. - + Aquesta opció permet a Mesen carregar els paquets d'alta resolució d'HDNes que trobi. Els paquets d'alta resolució han d'estar a la carpeta "HdPacks" dins d'una altra carpeta amb el mateix nom que la ROM. Exemple: Posem per cas que tenim una rom anomenada "LaMevaRom.nes", el seu paquet hauria d'estar a "HdPacks\LaMevaRom\hires.txt". Tria el tipus d'escalat i filtre de vídeo que s'utilitzaran quan es generin els fitxers PNG per al paquet d'alta resolució. Fes servir els filtres de preescalat per a generar les tiles a una escala major sense aplicar cap transformació als píxels. Aquesta opció només està disponible per a jocs de RAM de tipus CHR. Els jocs de RAM de tipus CHR no tenen "bancs" fixos - van sent creats dinàmicament pel codi del joc. Aquesta opció altera el funcionament a l'hora d'agrupar les tiles als fitxers PNG - un banc petit normalment donarà a lloc a menys fitxers PNG (tot i que depenent en el codi del joc, valors més alts poden produir millors resultats). diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml index 724dce86..d6d86460 100644 --- a/GUI.NET/Dependencies/resources.en.xml +++ b/GUI.NET/Dependencies/resources.en.xml @@ -787,8 +787,8 @@ Wave files (*.wav)|*.wav|All Files (*.*)|*.* Avi files (*.avi)|*.avi|All Files (*.*)|*.* Palette Files (*.pal)|*.pal|All Files (*.*)|*.* - All supported formats (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - All supported formats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* + All supported formats (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* + All supported formats (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test files (*.mtp)|*.mtp|All (*.*)|*.* All supported formats (*.cht, *.xml)|*.cht;*.xml Mesen Savestates (*.mst)|*.mst|All files (*.*)|*.* @@ -850,10 +850,11 @@ <empty> An error has occurred while trying to check for updates. Check your internet connection and try again. Error details: {0} Automatic updates are not enabled on this build - please download the latest version of the code and recompile Mesen to get the latest updates. - FDS bios not found. The bios is required to run FDS games. Select bios file now? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. BIOS SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? + Disk {0} Side {1} File not found: {0} - The selected bios file is invalid. This option allows Mesen to load HDNes-format HD packs if they are found. HD Packs should be placed in the "HdPacks" folder in a subfolder matching the name of the ROM. e.g: MyRom.nes should have their HD Pack in "HdPacks\MyRom\hires.txt". Selects the scale and video filter to use when generating the PNG files for the HD Pack. Use the "Prescale" filters to generate the tiles at a larger scale without applying any transformation to the pixels. diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml index e184b54d..57b19083 100644 --- a/GUI.NET/Dependencies/resources.es.xml +++ b/GUI.NET/Dependencies/resources.es.xml @@ -774,8 +774,8 @@ Archivos wave (*.wav)|*.wav|Todos los archivos (*.*)|*.* Archivos avi (*.avi)|*.avi|Todos los archivos (*.*)|*.* Archivos pal (*.pal)|*.pal|Todos los archivos (*.*)|*.* - Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Todos los archivos (*.*)|*.* - Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES(*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Archivos IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Todos los archivos (*.*)|*.* + Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Todos los archivos (*.*)|*.* + Todos los formatos soportados (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES(*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Archivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Archivos ZIP (*.zip)|*.ZIP|Archivos 7-Zip (*.7z)|*.7z|Archivos IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Todos los archivos (*.*)|*.* Archivos de test (*.mtp)|*.mtp|Todos los archivos (*.*)|*.* Todos los formatos soportados (*.cht, *.xml)|*.cht;*.xml Partidas de juegos de Mesen (*.mst)|*.mst|Todos los archivos (*.*)|*.* @@ -835,10 +835,10 @@ <No hay copia de seguridad> Se ha producido un error en la búsqueda de actualizaciones. Compruebe su conexión a Internet e inténtelo de nuevo. Detalles del error: {0} Las actualizaciones automáticas no están habilitadas en esta compilación - por favor descarga la última versión del código y vuelve a compilar Mesen para obtener las últimas actualizaciones. - No se encontró una bios para FDS. Se requiere una bios para jugar a juegos FDS. ¿Desea seleccionar una bios manualmente? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? Disco {0} Cara {1} Archivo no encontrado: {0} - La bios seleccionada no es válida. Esta opción permite los paquetes de gráficos en alta resolución de carga Mesen en el mismo formato que los del emulador HDNes. Los paquetes de alta resolución deberán ser colocados en los "HdPacks" en una subcarpeta con el nombre de la ROM. Ejemplo: Un paquete para "MiRom.nes" debe estar colocado en "HdPacks\MiRom\hires.txt". Escoge el tipo de escalado y filtro de vídeo a usar cuando se generen los ficheros PNG para el paquete de alta resolución. Usa los filtros "Prescale" para generar las tiles a una escala mayor sin aplicar ninguna transformación a los píxeles. diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index c530930c..a63c5a76 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -787,8 +787,8 @@ Fichiers wave (*.wav)|*.wav|Tous les fichiers (*.*)|*.* Fichiers avi (*.avi)|*.avi|Tous les fichiers (*.*)|*.* Fichier de palette (*.pal)|*.pal|Tous les fichiers (*.*)|*.* - Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Tous les fichiers (*.*)|*.* - Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Fichiers IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Tous les fichiers (*.*)|*.* + Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Tous les fichiers (*.*)|*.* + Tous les formats supportés (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms du Famicom Disk System (*.fds)|*.FDS|Fichiers NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Fichiers ZIP (*.zip)|*.ZIP|Fichiers 7-Zip (*.7z)|*.7z|Fichiers IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Tous les fichiers (*.*)|*.* Fichiers de test (*.mtp)|*.mtp|Tous les fichiers (*.*)|*.* Tous les formats supportés (*.cht, *.xml)|*.cht;*.xml Sauvegardes d'états Mesen (*.mst)|*.mst|Tous les fichiers (*.*)|*.* @@ -849,10 +849,10 @@ <aucune sauvegarde> Une erreur s'est produite lors de la recherche de mises-à-jour. Vérifier votre connexion internet et essayez à nouveau. Détails de l'erreur : {0} Les mises-à-jour automatiques ne sont pas disponibles avec votre build - s.v.p télécharger la dernière version du code et recompiler Mesen pour avoir accès à la version la plus récente. - Un bios pour le FDS n'a pas été trouvé. Le bios est requis pour jouer à des jeux de FDS. Voulez-vous sélectionnez un bios maintenant? + Un bios est requis pour ce jeu. Nom du fichier : {0} Taille : {1} octets Voulez-vous choisir le fichier bios maintenant? + Le fichier sélectionné ne correspond pas au bios requis pour ce jeu. SHA-256 requis: {0} SHA-256 du fichier sélectionné: {1} Voulez-vous quand même utiliser ce fichier? Disque {0} Côté {1} Fichier non trouvé: {0} - Le bios sélectionné est invalide. Cette option permet à Mesen de charger des packages de graphiques haute-résolution dans le même format que l'émulateur HDNes. Les packages haute-résolution doivent être placés dans le dossier "HdPacks", dans un sous-dossier correspondant au nom du ROM. Exemple : Un package pour "MonRom.nes" doit être placé dans "HdPacks\MonRom\hires.txt". Sélectionne la taille et le filtre à utiliser lors de la génération des fichiers PNG pour le HD Pack. Utilisez les filtres "Prescale" pour générer l'image avec une plus grande taille sans appliquer un filtre aux pixels. diff --git a/GUI.NET/Dependencies/resources.it.xml b/GUI.NET/Dependencies/resources.it.xml index 254aded9..b998ae8d 100644 --- a/GUI.NET/Dependencies/resources.it.xml +++ b/GUI.NET/Dependencies/resources.it.xml @@ -787,8 +787,8 @@ Wave files (*.wav)|*.wav|All Files (*.*)|*.* Avi files (*.avi)|*.avi|All Files (*.*)|*.* Palette Files (*.pal)|*.pal|All Files (*.*)|*.* - Tutti i formati supportati (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - Tutti i formati supportati (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *..unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* + Tutti i formati supportati (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* + Tutti i formati supportati (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *..unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test file (*.mtp)|*.mtp|All (*.*)|*.* Tutti i formati supportati (*.cht, *.xml)|*.cht;*.xml Mesen Savestati (*.mst)|*.mst|All files (*.*)|*.* @@ -850,10 +850,10 @@ <vuoto> Si è verificato un errore durante il tentativo di verifica presenza aggiornamenti. Controlla la tua connessione Internet e riprova. Dettagli errore: {0} Gli aggiornamenti automatici non sono abilitati su questa build - si prega di scaricare l'ultima versione del codice e ricompilare Mesen per ottenere gli ultimi aggiornamenti. - Bios FDS non trovato. Il bios è richiesto per eseguire i giochi FDS. Seleziona il file bios adesso? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? Disco {0} Lato {1} File non trovato: {0} - Il file bios selezionato non è valido. Questa opzione consente a Mesen di caricare i pacchetti HD in formato HDNes se trovati. I pacchetti HD devono essere collocati nella cartella "HdPacks" in una sottocartella che corrisponde al nome della ROM. ad es.: MyRom.nes dovrebbe avere il proprio HD Pack in "HdPacks\MyRom\hires.txt". Seleziona la dimensione e il filtro video da utilizzare durante la generazione dei file PNG per l'HD Pack. Usa i filtri "Prescale" per generare le tile su una scala più ampia senza applicare alcuna trasformazione ai pixel. diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index b966e7db..b148c590 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -775,8 +775,8 @@ WAVファイル (*.wav)|*.wav|すべてのファイル (*.*)|*.* AVIファイル (*.avi)|*.avi|すべてのファイル (*.*)|*.* パレットファイル (*.pal)|*.pal|すべてのファイル (*.*)|*.* - 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif)|*.NES;*.ZIP;*.FDS;*.7z;*.NSF;*.NSFE;*.UNF;*.UNIF|ファミコンゲーム (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|すべてのファイル (*.*)|*.* - 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|ファミコンゲーム (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|パッチファイル (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|すべてのファイル (*.*)|*.* + 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.FDS;*.7z;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|ファミコンゲーム (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|すべてのファイル (*.*)|*.* + 対応するすべてのファイル (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|ファミコンゲーム (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|ファミコンディスクシステムのゲーム (*.fds)|*.FDS|NSFファイル (*.nsf, *.nsfe)|*.NSF;*.NSFE|ZIPファイル (*.zip)|*.ZIP|7-Zipファイル (*.7z)|*.7z|パッチファイル (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|すべてのファイル (*.*)|*.* テストファイル (*.mtp)|*.mtp|すべてのファイル (*.*)|*.* 対応するすべてのファイル (*.cht, *.xml)|*.cht;*.xml Mesenのクイックセーブデータ (*.mst)|*.mst|すべてのファイル (*.*)|*.* @@ -837,10 +837,10 @@ <なし> アップデートを確認する時にエラーが発生しました。ネット接続を確認してから、再試行してください。 エラーの詳細: {0} このビルドでは自動更新は出来ません。最新版を使うためにはコードの最新版をダウンロードしてビルドしてください。 - ファミコンディスクシステム(FDS)のゲームをロードするためにFDSのBIOSファイルは必要です。 FDSのBIOSファイルを選びますか? + このゲームを起動するにはBIOSファイルが必要です。 ファイル: {0} 容量: {1} バイト BIOSフィアルを選択しますか? + 選んだファイルは必要なファイルと一致しませんでした. 必要なSHA-256: {0} 選んだファイルのSHA-256: {1} それでもこのファイルを使ってみますか? ディスク{0} {1}面 ファイルが見つかりません: {0} - 選んだBIOSファイルは使えません。 このオプションを有効にすれば、MesenはHDNesのようにHDパックをロード出来るようになります。 HDパックはMesenのフォルダの中にある「HdPacks」のフォルダにゲームと同じ名前のサブフォルダに置くと自動的にロードされます。 例)ゲームファイルは「MyRom.nes」なら、「HdPacks\MyRom」にHDパックを置くとロードされます。 Selects the scale and video filter to use when generating the PNG files for the HD Pack. Use the "Prescale" filters to generate the tiles at a larger scale without applying any transformation to the pixels. diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml index 93086f86..120a5be1 100644 --- a/GUI.NET/Dependencies/resources.pt.xml +++ b/GUI.NET/Dependencies/resources.pt.xml @@ -787,8 +787,8 @@ Arquivos wave (*.wav)|*.wav|Todos os arquivos (*.*)|*.* Arquivos avi (*.avi)|*.avi|Todos os arquivos (*.*)|*.* Arquivos pal (*.pal)|*.pal|Todos os arquivos (*.*)|*.* - Todos os formatos compatíveis (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Todos os arquivos (*.*)|*.* - Todos os formatos compatíveis (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|Roms de NES(*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Arquivos IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Todos os arquivos (*.*)|*.* + Todos os formatos compatíveis (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Todos os arquivos (*.*)|*.* + Todos os formatos compatíveis (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|Roms de NES(*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Roms de Famicom Disk System (*.fds)|*.FDS|Arquivos NSF (*.nsf, *.nsfe)|*.NSF;*.NSFE|Arquivos ZIP (*.zip)|*.ZIP|Arquivos 7-Zip (*.7z)|*.7z|Arquivos IPS/UPS/BPS (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|Todos os arquivos (*.*)|*.* Arquivos de teste (*.mtp)|*.mtp|Todos os arquivos (*.*)|*.* Todos os formatos compatíveis (*.cht, *.xml)|*.cht;*.xml Estados salvos do Mesen (*.mst)|*.mst|Todos os arquivos (*.*)|*.* @@ -850,10 +850,10 @@ <Não há estado salvo> Houve um erro na busca por atualizações. Verifique sua conexão com a internet e tente de novo. Detalhes do erro: {0} As atualizações automáticas não estão ativadas nesta compilação - baixe a versão mais recente do código e recompile o Mesen para obter as atualizações mais recentes. - Não foi encontrada uma bios para o FDS. É preciso uma bios para jogos do FDS. Deseja selecionar uma bios manualmente? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? Disco {0} Lado {1} Arquivo não encontrado: {0} - A bios selecionada é inválida. Esta opção permite os pacotes de gráficos de alta resolução sejam carregados no mesmo formato que os do emulador HDNes. Os pacotes de alta resolução devem ser colocados nos "HdPacks" em uma subpasta com o mesmo nome da ROM. Exemplo: Um pacote para "MinhaRom.nes" deve ser colocado em "HdPacks\MinhaRom\hires.txt". Seleciona a escala e o filtro de vídeo a serem usados ao gerar os arquivos PNG para o Pacote HD. Usa os filtros "Preescala" para gerar os tiles em uma escala maior sem aplicar qualquer transformação aos pixels. diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml index 1a2be75d..f3d0ec5f 100644 --- a/GUI.NET/Dependencies/resources.ru.xml +++ b/GUI.NET/Dependencies/resources.ru.xml @@ -775,8 +775,8 @@ Wave файлы (*.wav)|*.wav|All Files (*.*)|*.* Avi файлы (*.avi)|*.avi|All Files (*.*)|*.* Файлы палитры (*.pal)|*.pal|All Files (*.*)|*.* - Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* + Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* + Все поддерживаемые форматы (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test files (*.mtp)|*.mtp|All (*.*)|*.* Все поддерживаемые форматы (*.cht, *.xml)|*.cht;*.xml Mesen Savestates (*.mst)|*.mst|All Files (*.*)|*.* @@ -837,10 +837,10 @@ <пусто> Ошибка при проверке обновлений. Проверьте ваше соединение с интернетом и попробуйте ещё раз. Подробно: {0} Automatic updates are not enabled on this build - please download the latest version of the code and recompile Mesen to get the latest updates. - FDS BIOS не найден. BIOS необходим для запуска FDS игр. Выбрать BIOS сейчас? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? Диск {0} Сторона {1} Файл не найден: {0} - Выбранный биос некорректный. Данная опция позволяет использовать HD packs для эмулятора HDNes если они найдены. HD Packs должны быть помещены в папку "HdPacks" в папке с именем совпадающем с именем ROM. например: HD Pack для MyRom.nes должны лежать в "HdPacks\MyRom\hires.txt". Selects the scale and video filter to use when generating the PNG files for the HD Pack. Use the "Prescale" filters to generate the tiles at a larger scale without applying any transformation to the pixels. diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml index e70808b5..8635e077 100644 --- a/GUI.NET/Dependencies/resources.uk.xml +++ b/GUI.NET/Dependencies/resources.uk.xml @@ -775,8 +775,8 @@ Wave файли (*.wav)|*.wav|All Files (*.*)|*.* Avi файли (*.avi)|*.avi|All Files (*.*)|*.* Файли палiтр (*.pal)|*.pal|All Files (*.*)|*.* - Всі підтримувані формати (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* - Всі підтримувані формати (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* + Всі підтримувані формати (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.* + Всі підтримувані формати (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES Roms (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom Disk System Roms (*.fds)|*.FDS|NSF files (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|IPS/UPS/BPS Patches (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|All (*.*)|*.* Test files (*.mtp)|*.mtp|All (*.*)|*.* Всі підтримувані формати (*.cht, *.xml)|*.cht;*.xml Mesen Savestates (*.mst)|*.mst|All Files (*.*)|*.* @@ -837,10 +837,10 @@ <немає резервної копії> Не вдалося перевірити оновлення. Перевірте ваше з'єднання з інтернетом і спробуйте ще раз. Детально: {0} Автоматичні оновлення не включені в цій збірці - будь ласка завантажте останню версію коду та перекомпілюйте Mesen щоб отримати останні оновлення. - Біос для FDS не був знайдений. Біос потрібен, щоб грати в ігри FDS. Ви хочете вибрати BIOS зараз? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? Диск {0} Сторона {1} Файл не знайдено: {0} - Обраний биос некоректний. Дана опція дозволяє використовувати HD packs для емулятора HDNes якщо вони знайдени. HD Packs повинні бути поміщені в папку "HdPacks" в папці з ім'ям збігається з ім'ям ROM. наприклад: HD Pack для MyRom.nes повинні лежати в "HdPacks\MyRom\hires.txt". Вибирає розмір і фільтр для використання при створенні файлів PNG для HD Pack. Використовуйте фільтри «Prescale» для генерації зображення з великим розміром без застосування фільтра до пікселів. diff --git a/GUI.NET/Dependencies/resources.zh.xml b/GUI.NET/Dependencies/resources.zh.xml index 01450402..2bd1d4c5 100644 --- a/GUI.NET/Dependencies/resources.zh.xml +++ b/GUI.NET/Dependencies/resources.zh.xml @@ -799,8 +799,8 @@ 波形文件 (*.wav)|*.wav|所有文件 (*.*)|*.* AVI 视频 (*.avi)|*.avi|所有文件 (*.*)|*.* 调色板 (*.pal)|*.pal|所有文件 (*.*)|*.* - 所有支持的格式 (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES ROM (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom 磁盘 (*.fds)|*.FDS|NSF 音乐 (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP 档案 (*.zip)|*.ZIP|7-Zip 档案 (*.7z)|*.7z|所有文件 (*.*)|*.* - 所有支持的格式 (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF|NES ROM (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom 磁盘 (*.fds)|*.FDS|NSF 音乐 (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP 档案 (*.zip)|*.ZIP|7-Zip 档案 (*.7z)|*.7z|IPS/UPS/BPS 补丁 (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|所有文件 (*.*)|*.* + 所有支持的格式 (*.nes, *.zip, *.7z, *.nsf, *.nsfe, *.fds, *.unf, *.unif, *.studybox)|*.NES;*.ZIP;*.7z;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES ROM (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom 磁盘 (*.fds)|*.FDS|NSF 音乐 (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP 档案 (*.zip)|*.ZIP|7-Zip 档案 (*.7z)|*.7z|所有文件 (*.*)|*.* + 所有支持的格式 (*.nes, *.zip, *.7z, *.fds, *.nsf, *.nsfe, *.unf, *.unif, *.studybox, *.ips, *.bps, *.ups)|*.NES;*.ZIP;*.7z;*.IPS;*.BPS;*.UPS;*.FDS;*.NSF;*.NSFE;*.UNF;*.UNIF;*.STUDYBOX|NES ROM (*.nes, *.unf, *.unif)|*.NES;*.UNF;*.UNIF|Famicom 磁盘 (*.fds)|*.FDS|NSF 音乐 (*.nsf, *.nsfe)|*.nsf;*.nsfe|ZIP 档案 (*.zip)|*.ZIP|7-Zip 档案 (*.7z)|*.7z|IPS/UPS/BPS 补丁 (*.ips, *.bps, *.ups)|*.IPS;*.BPS;*.UPS|所有文件 (*.*)|*.* 测试文件 (*.mtp)|*.mtp|所有文件 (*.*)|*.* 所有支持的格式 (*.cht, *.xml)|*.cht;*.xml Mesen 进度 (*.mst)|*.mst|所有文件 (*.*)|*.* @@ -858,10 +858,10 @@ <空> 检查更新时出错,请确认网络通畅然后再试. 详情: {0} 此编译版未启用自动更新,要想获得最新版 Mesen,请下载最新版源码来编译. - 缺少 FDS 游戏所需 BIOS. 是否要立即手动指定? + A bios file is required to run this game. Filename: {0} Size: {1} bytes Select bios file now? + The selected file does not match the bios required for this game. Expected SHA-256: {0} Selected file's SHA-256: {1} Would you like to use this file anyway? 磁盘 {0} 的 {1} 面 文件 {0} 未找到 - 所选 BIOS 无效. 载入 HDNes 格式 HD 包. HD 包应放置在 "HdPacks" 文件夹下对应 ROM 名的子文件夹中. 例: MyRom.nes 对应 "HdPacks\MyRom\hires.txt". 给 HD 包所用 PNG 文件选择缩放和视频过滤参数 使用【预缩放】可以创建出缩放比例更大的块,同时像素不变形. 仅用于 CHR RAM 游戏,这类游戏的岸数据用代码动态创建,不固定. 此选项会影响 HD 包构造器给 PNG 组织块的行为,通常来说,岸越小,PNG 文件就越少. 但有些游戏可能需要把数值调高才能获得更好的效果. diff --git a/GUI.NET/Forms/frmMain.Tools.cs b/GUI.NET/Forms/frmMain.Tools.cs index 5662a85a..75ea7897 100644 --- a/GUI.NET/Forms/frmMain.Tools.cs +++ b/GUI.NET/Forms/frmMain.Tools.cs @@ -132,6 +132,7 @@ namespace Mesen.GUI.Forms gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.unf", searchOptions)); gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.unif", searchOptions)); gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.fds", searchOptions)); + gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.studybox", searchOptions)); if(searchOptions == SearchOption.AllDirectories) { //When loading from a user-specified folder, assume zip/7z files will likely contain a ROM diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index 087a3e74..3d22f47c 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -741,9 +741,14 @@ namespace Mesen.GUI.Forms })); break; - case InteropEmu.ConsoleNotificationType.FdsBiosNotFound: + case InteropEmu.ConsoleNotificationType.BiosNotFound: this.BeginInvoke((MethodInvoker)(() => { - SelectFdsBiosPrompt(); + RomFormat format = ((RomFormat)e.Parameter); + if(format == RomFormat.Fds) { + SelectBiosPrompt("FdsBios.bin", 0x2000, RomFormat.Fds); + } else if(format == RomFormat.StudyBox) { + SelectBiosPrompt("StudyBox.bin", 0x40000, RomFormat.StudyBox); + } })); break; @@ -1352,21 +1357,10 @@ namespace Mesen.GUI.Forms return base.ProcessCmdKey(ref msg, keyData); } - private void SelectFdsBiosPrompt() + private void SelectBiosPrompt(string fileName, int fileSize, RomFormat format) { - if(MesenMsgBox.Show("FdsBiosNotFound", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { - using(OpenFileDialog ofd = new OpenFileDialog()) { - ofd.SetFilter(ResourceHelper.GetMessage("FilterAll")); - if(ofd.ShowDialog(this) == DialogResult.OK) { - string hash = MD5Helper.GetMD5Hash(ofd.FileName).ToLowerInvariant(); - if(hash == "ca30b50f880eb660a320674ed365ef7a" || hash == "c1a9e9415a6adde3c8563c622d4c9fce") { - File.Copy(ofd.FileName, Path.Combine(ConfigManager.HomeFolder, "FdsBios.bin")); - LoadROM(_currentRomPath.Value, ConfigManager.Config.PreferenceInfo.AutoLoadIpsPatches); - } else { - MesenMsgBox.Show("InvalidFdsBios", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } + if(BiosHelper.RequestBiosFile(fileName, fileSize, format)) { + LoadROM(_currentRomPath.Value, ConfigManager.Config.PreferenceInfo.AutoLoadIpsPatches); } } diff --git a/GUI.NET/GUI.NET.csproj b/GUI.NET/GUI.NET.csproj index 9f398ae7..38ce50dc 100644 --- a/GUI.NET/GUI.NET.csproj +++ b/GUI.NET/GUI.NET.csproj @@ -238,6 +238,7 @@ + diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index e5daaf42..6d041342 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -972,7 +972,7 @@ namespace Mesen.GUI PpuFrameDone = 9, MovieEnded = 10, ResolutionChanged = 11, - FdsBiosNotFound = 12, + BiosNotFound = 12, ConfigChanged = 13, DisconnectedFromServer = 14, PpuViewerDisplayFrame = 15, @@ -1778,6 +1778,7 @@ namespace Mesen.GUI Unif = 2, Fds = 3, Nsf = 4, + StudyBox = 5 } public class RomInfo diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index 3efdd2d7..51cce9d7 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -409,10 +409,13 @@ namespace InteropEmu { interopRomInfo.FilePrgOffset = romInfo.FilePrgOffset; if(romInfo.Hash.Sha1.size() == 40) { memcpy(interopRomInfo.Sha1, romInfo.Hash.Sha1.c_str(), 40); + } else { + memset(interopRomInfo.Sha1, 0, 40); } } else { RomLoader romLoader(true); - if(romLoader.LoadFile(romPath)) { + VirtualFile romFile = romPath; + if(romLoader.LoadFile(romFile)) { RomData romData = romLoader.GetRomData(); _returnString = romPath; diff --git a/Libretro/Makefile.common b/Libretro/Makefile.common index 3815c716..7d45cd14 100644 --- a/Libretro/Makefile.common +++ b/Libretro/Makefile.common @@ -107,6 +107,7 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \ $(CORE_DIR)/StereoCombFilter.cpp \ $(CORE_DIR)/StereoDelayFilter.cpp \ $(CORE_DIR)/StereoPanningFilter.cpp \ + $(CORE_DIR)/StudyBoxLoader.cpp \ $(CORE_DIR)/TraceLogger.cpp \ $(CORE_DIR)/UnifLoader.cpp \ $(CORE_DIR)/VideoDecoder.cpp \ @@ -139,6 +140,7 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \ $(UTIL_DIR)/Timer.cpp \ $(UTIL_DIR)/UpsPatcher.cpp \ $(UTIL_DIR)/UTF8Util.cpp \ + $(UTIL_DIR)/WavReader.cpp \ $(UTIL_DIR)/ZipReader.cpp \ $(UTIL_DIR)/ZipWriter.cpp \ $(UTIL_DIR)/ZmbvCodec.cpp \ diff --git a/Libretro/libretro.cpp b/Libretro/libretro.cpp index 0c9f0444..9d5d5326 100644 --- a/Libretro/libretro.cpp +++ b/Libretro/libretro.cpp @@ -171,7 +171,7 @@ extern "C" { { MesenRamState, "Default power-on state for RAM; All 0s (Default)|All 1s|Random Values" }, { MesenFdsAutoSelectDisk, "FDS: Automatically insert disks; disabled|enabled" }, { MesenFdsFastForwardLoad, "FDS: Fast forward while loading; disabled|enabled" }, - { MesenAudioSampleRate, "Sound Output Sample Rate; 11025|22050|44100|48000|96000|192000|384000" }, + { MesenAudioSampleRate, "Sound Output Sample Rate; 96000|192000|384000|11025|22050|44100|48000" }, { NULL, NULL }, }; diff --git a/Utilities/CRC32.cpp b/Utilities/CRC32.cpp index 89aab9b7..c74c990d 100644 --- a/Utilities/CRC32.cpp +++ b/Utilities/CRC32.cpp @@ -1,20 +1,37 @@ +//Adapted from https://github.com/stbrumme/crc32/blob/master/Crc32.cpp +//zlib license + #include "stdafx.h" #include "CRC32.h" -void CRC32::AddData(const uint8_t* pData, const std::streamoff length) -{ - uint8_t* pCur = (uint8_t*)pData; - for(std::streamoff remaining = length; remaining--; ++pCur) { - _crc = (_crc >> 8) ^ kCrc32Table[(_crc ^ *pCur) & 0xff]; - } -} +const size_t MaxSlice = 16; +extern const uint32_t Crc32Lookup[MaxSlice][256]; + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif + +// define endianess and some integer data types +#if defined(_MSC_VER) || defined(__MINGW32__) + // Windows always little endian + #define __BYTE_ORDER __LITTLE_ENDIAN +#else + // defines __BYTE_ORDER as __LITTLE_ENDIAN or __BIG_ENDIAN + #include +#endif + +// abort if byte order is undefined +#if !defined(__BYTE_ORDER) +#error undefined byte order, compile with -D__BYTE_ORDER=1234 (if little endian) or -D__BYTE_ORDER=4321 (big endian) +#endif uint32_t CRC32::GetCRC(uint8_t *buffer, std::streamoff length) { - CRC32 crc; - crc.AddData(buffer, length); - return ~(crc._crc); + return crc32_16bytes(buffer, length, 0); } uint32_t CRC32::GetCRC(string filename) @@ -32,9 +49,636 @@ uint32_t CRC32::GetCRC(string filename) file.read((char*)buffer, fileSize); file.close(); - crc = GetCRC(buffer, fileSize); + crc = crc32_16bytes(buffer, fileSize, 0); delete[] buffer; } - return ~crc; -} \ No newline at end of file + return crc; +} + +uint32_t CRC32::crc32_16bytes(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint32_t* current = (const uint32_t*)data; + + // enabling optimization (at least -O2) automatically unrolls the inner for-loop + const size_t Unroll = 4; + const size_t BytesAtOnce = 16 * Unroll; + + while(length >= BytesAtOnce) { + for(size_t unrolling = 0; unrolling < Unroll; unrolling++) { + #if __BYTE_ORDER == __BIG_ENDIAN + uint32_t one = *current++ ^ swap(crc); + uint32_t two = *current++; + uint32_t three = *current++; + uint32_t four = *current++; + crc = Crc32Lookup[0][four & 0xFF] ^ + Crc32Lookup[1][(four >> 8) & 0xFF] ^ + Crc32Lookup[2][(four >> 16) & 0xFF] ^ + Crc32Lookup[3][(four >> 24) & 0xFF] ^ + Crc32Lookup[4][three & 0xFF] ^ + Crc32Lookup[5][(three >> 8) & 0xFF] ^ + Crc32Lookup[6][(three >> 16) & 0xFF] ^ + Crc32Lookup[7][(three >> 24) & 0xFF] ^ + Crc32Lookup[8][two & 0xFF] ^ + Crc32Lookup[9][(two >> 8) & 0xFF] ^ + Crc32Lookup[10][(two >> 16) & 0xFF] ^ + Crc32Lookup[11][(two >> 24) & 0xFF] ^ + Crc32Lookup[12][one & 0xFF] ^ + Crc32Lookup[13][(one >> 8) & 0xFF] ^ + Crc32Lookup[14][(one >> 16) & 0xFF] ^ + Crc32Lookup[15][(one >> 24) & 0xFF]; + #else + uint32_t one = *current++ ^ crc; + uint32_t two = *current++; + uint32_t three = *current++; + uint32_t four = *current++; + crc = Crc32Lookup[0][(four >> 24) & 0xFF] ^ + Crc32Lookup[1][(four >> 16) & 0xFF] ^ + Crc32Lookup[2][(four >> 8) & 0xFF] ^ + Crc32Lookup[3][four & 0xFF] ^ + Crc32Lookup[4][(three >> 24) & 0xFF] ^ + Crc32Lookup[5][(three >> 16) & 0xFF] ^ + Crc32Lookup[6][(three >> 8) & 0xFF] ^ + Crc32Lookup[7][three & 0xFF] ^ + Crc32Lookup[8][(two >> 24) & 0xFF] ^ + Crc32Lookup[9][(two >> 16) & 0xFF] ^ + Crc32Lookup[10][(two >> 8) & 0xFF] ^ + Crc32Lookup[11][two & 0xFF] ^ + Crc32Lookup[12][(one >> 24) & 0xFF] ^ + Crc32Lookup[13][(one >> 16) & 0xFF] ^ + Crc32Lookup[14][(one >> 8) & 0xFF] ^ + Crc32Lookup[15][one & 0xFF]; + #endif + } + + length -= BytesAtOnce; + } + + const uint8_t* currentChar = (const uint8_t*)current; + // remaining 1 to 63 bytes (standard algorithm) + while(length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + +const uint32_t Crc32Lookup[MaxSlice][256] = +{ + { + 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3, + 0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, + 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, + 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, + 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B, + 0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, + 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, + 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, + 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, + 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, + 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457, + 0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, + 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB, + 0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, + 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, + 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, + 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683, + 0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, + 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7, + 0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, + 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, + 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, + 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F, + 0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, + 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713, + 0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, + 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, + 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, + 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB, + 0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, + 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF, + 0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D, + } + ,{ + 0x00000000,0x191B3141,0x32366282,0x2B2D53C3,0x646CC504,0x7D77F445,0x565AA786,0x4F4196C7, + 0xC8D98A08,0xD1C2BB49,0xFAEFE88A,0xE3F4D9CB,0xACB54F0C,0xB5AE7E4D,0x9E832D8E,0x87981CCF, + 0x4AC21251,0x53D92310,0x78F470D3,0x61EF4192,0x2EAED755,0x37B5E614,0x1C98B5D7,0x05838496, + 0x821B9859,0x9B00A918,0xB02DFADB,0xA936CB9A,0xE6775D5D,0xFF6C6C1C,0xD4413FDF,0xCD5A0E9E, + 0x958424A2,0x8C9F15E3,0xA7B24620,0xBEA97761,0xF1E8E1A6,0xE8F3D0E7,0xC3DE8324,0xDAC5B265, + 0x5D5DAEAA,0x44469FEB,0x6F6BCC28,0x7670FD69,0x39316BAE,0x202A5AEF,0x0B07092C,0x121C386D, + 0xDF4636F3,0xC65D07B2,0xED705471,0xF46B6530,0xBB2AF3F7,0xA231C2B6,0x891C9175,0x9007A034, + 0x179FBCFB,0x0E848DBA,0x25A9DE79,0x3CB2EF38,0x73F379FF,0x6AE848BE,0x41C51B7D,0x58DE2A3C, + 0xF0794F05,0xE9627E44,0xC24F2D87,0xDB541CC6,0x94158A01,0x8D0EBB40,0xA623E883,0xBF38D9C2, + 0x38A0C50D,0x21BBF44C,0x0A96A78F,0x138D96CE,0x5CCC0009,0x45D73148,0x6EFA628B,0x77E153CA, + 0xBABB5D54,0xA3A06C15,0x888D3FD6,0x91960E97,0xDED79850,0xC7CCA911,0xECE1FAD2,0xF5FACB93, + 0x7262D75C,0x6B79E61D,0x4054B5DE,0x594F849F,0x160E1258,0x0F152319,0x243870DA,0x3D23419B, + 0x65FD6BA7,0x7CE65AE6,0x57CB0925,0x4ED03864,0x0191AEA3,0x188A9FE2,0x33A7CC21,0x2ABCFD60, + 0xAD24E1AF,0xB43FD0EE,0x9F12832D,0x8609B26C,0xC94824AB,0xD05315EA,0xFB7E4629,0xE2657768, + 0x2F3F79F6,0x362448B7,0x1D091B74,0x04122A35,0x4B53BCF2,0x52488DB3,0x7965DE70,0x607EEF31, + 0xE7E6F3FE,0xFEFDC2BF,0xD5D0917C,0xCCCBA03D,0x838A36FA,0x9A9107BB,0xB1BC5478,0xA8A76539, + 0x3B83984B,0x2298A90A,0x09B5FAC9,0x10AECB88,0x5FEF5D4F,0x46F46C0E,0x6DD93FCD,0x74C20E8C, + 0xF35A1243,0xEA412302,0xC16C70C1,0xD8774180,0x9736D747,0x8E2DE606,0xA500B5C5,0xBC1B8484, + 0x71418A1A,0x685ABB5B,0x4377E898,0x5A6CD9D9,0x152D4F1E,0x0C367E5F,0x271B2D9C,0x3E001CDD, + 0xB9980012,0xA0833153,0x8BAE6290,0x92B553D1,0xDDF4C516,0xC4EFF457,0xEFC2A794,0xF6D996D5, + 0xAE07BCE9,0xB71C8DA8,0x9C31DE6B,0x852AEF2A,0xCA6B79ED,0xD37048AC,0xF85D1B6F,0xE1462A2E, + 0x66DE36E1,0x7FC507A0,0x54E85463,0x4DF36522,0x02B2F3E5,0x1BA9C2A4,0x30849167,0x299FA026, + 0xE4C5AEB8,0xFDDE9FF9,0xD6F3CC3A,0xCFE8FD7B,0x80A96BBC,0x99B25AFD,0xB29F093E,0xAB84387F, + 0x2C1C24B0,0x350715F1,0x1E2A4632,0x07317773,0x4870E1B4,0x516BD0F5,0x7A468336,0x635DB277, + 0xCBFAD74E,0xD2E1E60F,0xF9CCB5CC,0xE0D7848D,0xAF96124A,0xB68D230B,0x9DA070C8,0x84BB4189, + 0x03235D46,0x1A386C07,0x31153FC4,0x280E0E85,0x674F9842,0x7E54A903,0x5579FAC0,0x4C62CB81, + 0x8138C51F,0x9823F45E,0xB30EA79D,0xAA1596DC,0xE554001B,0xFC4F315A,0xD7626299,0xCE7953D8, + 0x49E14F17,0x50FA7E56,0x7BD72D95,0x62CC1CD4,0x2D8D8A13,0x3496BB52,0x1FBBE891,0x06A0D9D0, + 0x5E7EF3EC,0x4765C2AD,0x6C48916E,0x7553A02F,0x3A1236E8,0x230907A9,0x0824546A,0x113F652B, + 0x96A779E4,0x8FBC48A5,0xA4911B66,0xBD8A2A27,0xF2CBBCE0,0xEBD08DA1,0xC0FDDE62,0xD9E6EF23, + 0x14BCE1BD,0x0DA7D0FC,0x268A833F,0x3F91B27E,0x70D024B9,0x69CB15F8,0x42E6463B,0x5BFD777A, + 0xDC656BB5,0xC57E5AF4,0xEE530937,0xF7483876,0xB809AEB1,0xA1129FF0,0x8A3FCC33,0x9324FD72, + }, + + { + 0x00000000,0x01C26A37,0x0384D46E,0x0246BE59,0x0709A8DC,0x06CBC2EB,0x048D7CB2,0x054F1685, + 0x0E1351B8,0x0FD13B8F,0x0D9785D6,0x0C55EFE1,0x091AF964,0x08D89353,0x0A9E2D0A,0x0B5C473D, + 0x1C26A370,0x1DE4C947,0x1FA2771E,0x1E601D29,0x1B2F0BAC,0x1AED619B,0x18ABDFC2,0x1969B5F5, + 0x1235F2C8,0x13F798FF,0x11B126A6,0x10734C91,0x153C5A14,0x14FE3023,0x16B88E7A,0x177AE44D, + 0x384D46E0,0x398F2CD7,0x3BC9928E,0x3A0BF8B9,0x3F44EE3C,0x3E86840B,0x3CC03A52,0x3D025065, + 0x365E1758,0x379C7D6F,0x35DAC336,0x3418A901,0x3157BF84,0x3095D5B3,0x32D36BEA,0x331101DD, + 0x246BE590,0x25A98FA7,0x27EF31FE,0x262D5BC9,0x23624D4C,0x22A0277B,0x20E69922,0x2124F315, + 0x2A78B428,0x2BBADE1F,0x29FC6046,0x283E0A71,0x2D711CF4,0x2CB376C3,0x2EF5C89A,0x2F37A2AD, + 0x709A8DC0,0x7158E7F7,0x731E59AE,0x72DC3399,0x7793251C,0x76514F2B,0x7417F172,0x75D59B45, + 0x7E89DC78,0x7F4BB64F,0x7D0D0816,0x7CCF6221,0x798074A4,0x78421E93,0x7A04A0CA,0x7BC6CAFD, + 0x6CBC2EB0,0x6D7E4487,0x6F38FADE,0x6EFA90E9,0x6BB5866C,0x6A77EC5B,0x68315202,0x69F33835, + 0x62AF7F08,0x636D153F,0x612BAB66,0x60E9C151,0x65A6D7D4,0x6464BDE3,0x662203BA,0x67E0698D, + 0x48D7CB20,0x4915A117,0x4B531F4E,0x4A917579,0x4FDE63FC,0x4E1C09CB,0x4C5AB792,0x4D98DDA5, + 0x46C49A98,0x4706F0AF,0x45404EF6,0x448224C1,0x41CD3244,0x400F5873,0x4249E62A,0x438B8C1D, + 0x54F16850,0x55330267,0x5775BC3E,0x56B7D609,0x53F8C08C,0x523AAABB,0x507C14E2,0x51BE7ED5, + 0x5AE239E8,0x5B2053DF,0x5966ED86,0x58A487B1,0x5DEB9134,0x5C29FB03,0x5E6F455A,0x5FAD2F6D, + 0xE1351B80,0xE0F771B7,0xE2B1CFEE,0xE373A5D9,0xE63CB35C,0xE7FED96B,0xE5B86732,0xE47A0D05, + 0xEF264A38,0xEEE4200F,0xECA29E56,0xED60F461,0xE82FE2E4,0xE9ED88D3,0xEBAB368A,0xEA695CBD, + 0xFD13B8F0,0xFCD1D2C7,0xFE976C9E,0xFF5506A9,0xFA1A102C,0xFBD87A1B,0xF99EC442,0xF85CAE75, + 0xF300E948,0xF2C2837F,0xF0843D26,0xF1465711,0xF4094194,0xF5CB2BA3,0xF78D95FA,0xF64FFFCD, + 0xD9785D60,0xD8BA3757,0xDAFC890E,0xDB3EE339,0xDE71F5BC,0xDFB39F8B,0xDDF521D2,0xDC374BE5, + 0xD76B0CD8,0xD6A966EF,0xD4EFD8B6,0xD52DB281,0xD062A404,0xD1A0CE33,0xD3E6706A,0xD2241A5D, + 0xC55EFE10,0xC49C9427,0xC6DA2A7E,0xC7184049,0xC25756CC,0xC3953CFB,0xC1D382A2,0xC011E895, + 0xCB4DAFA8,0xCA8FC59F,0xC8C97BC6,0xC90B11F1,0xCC440774,0xCD866D43,0xCFC0D31A,0xCE02B92D, + 0x91AF9640,0x906DFC77,0x922B422E,0x93E92819,0x96A63E9C,0x976454AB,0x9522EAF2,0x94E080C5, + 0x9FBCC7F8,0x9E7EADCF,0x9C381396,0x9DFA79A1,0x98B56F24,0x99770513,0x9B31BB4A,0x9AF3D17D, + 0x8D893530,0x8C4B5F07,0x8E0DE15E,0x8FCF8B69,0x8A809DEC,0x8B42F7DB,0x89044982,0x88C623B5, + 0x839A6488,0x82580EBF,0x801EB0E6,0x81DCDAD1,0x8493CC54,0x8551A663,0x8717183A,0x86D5720D, + 0xA9E2D0A0,0xA820BA97,0xAA6604CE,0xABA46EF9,0xAEEB787C,0xAF29124B,0xAD6FAC12,0xACADC625, + 0xA7F18118,0xA633EB2F,0xA4755576,0xA5B73F41,0xA0F829C4,0xA13A43F3,0xA37CFDAA,0xA2BE979D, + 0xB5C473D0,0xB40619E7,0xB640A7BE,0xB782CD89,0xB2CDDB0C,0xB30FB13B,0xB1490F62,0xB08B6555, + 0xBBD72268,0xBA15485F,0xB853F606,0xB9919C31,0xBCDE8AB4,0xBD1CE083,0xBF5A5EDA,0xBE9834ED, + }, + + { + 0x00000000,0xB8BC6765,0xAA09C88B,0x12B5AFEE,0x8F629757,0x37DEF032,0x256B5FDC,0x9DD738B9, + 0xC5B428EF,0x7D084F8A,0x6FBDE064,0xD7018701,0x4AD6BFB8,0xF26AD8DD,0xE0DF7733,0x58631056, + 0x5019579F,0xE8A530FA,0xFA109F14,0x42ACF871,0xDF7BC0C8,0x67C7A7AD,0x75720843,0xCDCE6F26, + 0x95AD7F70,0x2D111815,0x3FA4B7FB,0x8718D09E,0x1ACFE827,0xA2738F42,0xB0C620AC,0x087A47C9, + 0xA032AF3E,0x188EC85B,0x0A3B67B5,0xB28700D0,0x2F503869,0x97EC5F0C,0x8559F0E2,0x3DE59787, + 0x658687D1,0xDD3AE0B4,0xCF8F4F5A,0x7733283F,0xEAE41086,0x525877E3,0x40EDD80D,0xF851BF68, + 0xF02BF8A1,0x48979FC4,0x5A22302A,0xE29E574F,0x7F496FF6,0xC7F50893,0xD540A77D,0x6DFCC018, + 0x359FD04E,0x8D23B72B,0x9F9618C5,0x272A7FA0,0xBAFD4719,0x0241207C,0x10F48F92,0xA848E8F7, + 0x9B14583D,0x23A83F58,0x311D90B6,0x89A1F7D3,0x1476CF6A,0xACCAA80F,0xBE7F07E1,0x06C36084, + 0x5EA070D2,0xE61C17B7,0xF4A9B859,0x4C15DF3C,0xD1C2E785,0x697E80E0,0x7BCB2F0E,0xC377486B, + 0xCB0D0FA2,0x73B168C7,0x6104C729,0xD9B8A04C,0x446F98F5,0xFCD3FF90,0xEE66507E,0x56DA371B, + 0x0EB9274D,0xB6054028,0xA4B0EFC6,0x1C0C88A3,0x81DBB01A,0x3967D77F,0x2BD27891,0x936E1FF4, + 0x3B26F703,0x839A9066,0x912F3F88,0x299358ED,0xB4446054,0x0CF80731,0x1E4DA8DF,0xA6F1CFBA, + 0xFE92DFEC,0x462EB889,0x549B1767,0xEC277002,0x71F048BB,0xC94C2FDE,0xDBF98030,0x6345E755, + 0x6B3FA09C,0xD383C7F9,0xC1366817,0x798A0F72,0xE45D37CB,0x5CE150AE,0x4E54FF40,0xF6E89825, + 0xAE8B8873,0x1637EF16,0x048240F8,0xBC3E279D,0x21E91F24,0x99557841,0x8BE0D7AF,0x335CB0CA, + 0xED59B63B,0x55E5D15E,0x47507EB0,0xFFEC19D5,0x623B216C,0xDA874609,0xC832E9E7,0x708E8E82, + 0x28ED9ED4,0x9051F9B1,0x82E4565F,0x3A58313A,0xA78F0983,0x1F336EE6,0x0D86C108,0xB53AA66D, + 0xBD40E1A4,0x05FC86C1,0x1749292F,0xAFF54E4A,0x322276F3,0x8A9E1196,0x982BBE78,0x2097D91D, + 0x78F4C94B,0xC048AE2E,0xD2FD01C0,0x6A4166A5,0xF7965E1C,0x4F2A3979,0x5D9F9697,0xE523F1F2, + 0x4D6B1905,0xF5D77E60,0xE762D18E,0x5FDEB6EB,0xC2098E52,0x7AB5E937,0x680046D9,0xD0BC21BC, + 0x88DF31EA,0x3063568F,0x22D6F961,0x9A6A9E04,0x07BDA6BD,0xBF01C1D8,0xADB46E36,0x15080953, + 0x1D724E9A,0xA5CE29FF,0xB77B8611,0x0FC7E174,0x9210D9CD,0x2AACBEA8,0x38191146,0x80A57623, + 0xD8C66675,0x607A0110,0x72CFAEFE,0xCA73C99B,0x57A4F122,0xEF189647,0xFDAD39A9,0x45115ECC, + 0x764DEE06,0xCEF18963,0xDC44268D,0x64F841E8,0xF92F7951,0x41931E34,0x5326B1DA,0xEB9AD6BF, + 0xB3F9C6E9,0x0B45A18C,0x19F00E62,0xA14C6907,0x3C9B51BE,0x842736DB,0x96929935,0x2E2EFE50, + 0x2654B999,0x9EE8DEFC,0x8C5D7112,0x34E11677,0xA9362ECE,0x118A49AB,0x033FE645,0xBB838120, + 0xE3E09176,0x5B5CF613,0x49E959FD,0xF1553E98,0x6C820621,0xD43E6144,0xC68BCEAA,0x7E37A9CF, + 0xD67F4138,0x6EC3265D,0x7C7689B3,0xC4CAEED6,0x591DD66F,0xE1A1B10A,0xF3141EE4,0x4BA87981, + 0x13CB69D7,0xAB770EB2,0xB9C2A15C,0x017EC639,0x9CA9FE80,0x241599E5,0x36A0360B,0x8E1C516E, + 0x866616A7,0x3EDA71C2,0x2C6FDE2C,0x94D3B949,0x090481F0,0xB1B8E695,0xA30D497B,0x1BB12E1E, + 0x43D23E48,0xFB6E592D,0xE9DBF6C3,0x516791A6,0xCCB0A91F,0x740CCE7A,0x66B96194,0xDE0506F1, + } + ,{ + 0x00000000,0x3D6029B0,0x7AC05360,0x47A07AD0,0xF580A6C0,0xC8E08F70,0x8F40F5A0,0xB220DC10, + 0x30704BC1,0x0D106271,0x4AB018A1,0x77D03111,0xC5F0ED01,0xF890C4B1,0xBF30BE61,0x825097D1, + 0x60E09782,0x5D80BE32,0x1A20C4E2,0x2740ED52,0x95603142,0xA80018F2,0xEFA06222,0xD2C04B92, + 0x5090DC43,0x6DF0F5F3,0x2A508F23,0x1730A693,0xA5107A83,0x98705333,0xDFD029E3,0xE2B00053, + 0xC1C12F04,0xFCA106B4,0xBB017C64,0x866155D4,0x344189C4,0x0921A074,0x4E81DAA4,0x73E1F314, + 0xF1B164C5,0xCCD14D75,0x8B7137A5,0xB6111E15,0x0431C205,0x3951EBB5,0x7EF19165,0x4391B8D5, + 0xA121B886,0x9C419136,0xDBE1EBE6,0xE681C256,0x54A11E46,0x69C137F6,0x2E614D26,0x13016496, + 0x9151F347,0xAC31DAF7,0xEB91A027,0xD6F18997,0x64D15587,0x59B17C37,0x1E1106E7,0x23712F57, + 0x58F35849,0x659371F9,0x22330B29,0x1F532299,0xAD73FE89,0x9013D739,0xD7B3ADE9,0xEAD38459, + 0x68831388,0x55E33A38,0x124340E8,0x2F236958,0x9D03B548,0xA0639CF8,0xE7C3E628,0xDAA3CF98, + 0x3813CFCB,0x0573E67B,0x42D39CAB,0x7FB3B51B,0xCD93690B,0xF0F340BB,0xB7533A6B,0x8A3313DB, + 0x0863840A,0x3503ADBA,0x72A3D76A,0x4FC3FEDA,0xFDE322CA,0xC0830B7A,0x872371AA,0xBA43581A, + 0x9932774D,0xA4525EFD,0xE3F2242D,0xDE920D9D,0x6CB2D18D,0x51D2F83D,0x167282ED,0x2B12AB5D, + 0xA9423C8C,0x9422153C,0xD3826FEC,0xEEE2465C,0x5CC29A4C,0x61A2B3FC,0x2602C92C,0x1B62E09C, + 0xF9D2E0CF,0xC4B2C97F,0x8312B3AF,0xBE729A1F,0x0C52460F,0x31326FBF,0x7692156F,0x4BF23CDF, + 0xC9A2AB0E,0xF4C282BE,0xB362F86E,0x8E02D1DE,0x3C220DCE,0x0142247E,0x46E25EAE,0x7B82771E, + 0xB1E6B092,0x8C869922,0xCB26E3F2,0xF646CA42,0x44661652,0x79063FE2,0x3EA64532,0x03C66C82, + 0x8196FB53,0xBCF6D2E3,0xFB56A833,0xC6368183,0x74165D93,0x49767423,0x0ED60EF3,0x33B62743, + 0xD1062710,0xEC660EA0,0xABC67470,0x96A65DC0,0x248681D0,0x19E6A860,0x5E46D2B0,0x6326FB00, + 0xE1766CD1,0xDC164561,0x9BB63FB1,0xA6D61601,0x14F6CA11,0x2996E3A1,0x6E369971,0x5356B0C1, + 0x70279F96,0x4D47B626,0x0AE7CCF6,0x3787E546,0x85A73956,0xB8C710E6,0xFF676A36,0xC2074386, + 0x4057D457,0x7D37FDE7,0x3A978737,0x07F7AE87,0xB5D77297,0x88B75B27,0xCF1721F7,0xF2770847, + 0x10C70814,0x2DA721A4,0x6A075B74,0x576772C4,0xE547AED4,0xD8278764,0x9F87FDB4,0xA2E7D404, + 0x20B743D5,0x1DD76A65,0x5A7710B5,0x67173905,0xD537E515,0xE857CCA5,0xAFF7B675,0x92979FC5, + 0xE915E8DB,0xD475C16B,0x93D5BBBB,0xAEB5920B,0x1C954E1B,0x21F567AB,0x66551D7B,0x5B3534CB, + 0xD965A31A,0xE4058AAA,0xA3A5F07A,0x9EC5D9CA,0x2CE505DA,0x11852C6A,0x562556BA,0x6B457F0A, + 0x89F57F59,0xB49556E9,0xF3352C39,0xCE550589,0x7C75D999,0x4115F029,0x06B58AF9,0x3BD5A349, + 0xB9853498,0x84E51D28,0xC34567F8,0xFE254E48,0x4C059258,0x7165BBE8,0x36C5C138,0x0BA5E888, + 0x28D4C7DF,0x15B4EE6F,0x521494BF,0x6F74BD0F,0xDD54611F,0xE03448AF,0xA794327F,0x9AF41BCF, + 0x18A48C1E,0x25C4A5AE,0x6264DF7E,0x5F04F6CE,0xED242ADE,0xD044036E,0x97E479BE,0xAA84500E, + 0x4834505D,0x755479ED,0x32F4033D,0x0F942A8D,0xBDB4F69D,0x80D4DF2D,0xC774A5FD,0xFA148C4D, + 0x78441B9C,0x4524322C,0x028448FC,0x3FE4614C,0x8DC4BD5C,0xB0A494EC,0xF704EE3C,0xCA64C78C, + }, + + { + 0x00000000,0xCB5CD3A5,0x4DC8A10B,0x869472AE,0x9B914216,0x50CD91B3,0xD659E31D,0x1D0530B8, + 0xEC53826D,0x270F51C8,0xA19B2366,0x6AC7F0C3,0x77C2C07B,0xBC9E13DE,0x3A0A6170,0xF156B2D5, + 0x03D6029B,0xC88AD13E,0x4E1EA390,0x85427035,0x9847408D,0x531B9328,0xD58FE186,0x1ED33223, + 0xEF8580F6,0x24D95353,0xA24D21FD,0x6911F258,0x7414C2E0,0xBF481145,0x39DC63EB,0xF280B04E, + 0x07AC0536,0xCCF0D693,0x4A64A43D,0x81387798,0x9C3D4720,0x57619485,0xD1F5E62B,0x1AA9358E, + 0xEBFF875B,0x20A354FE,0xA6372650,0x6D6BF5F5,0x706EC54D,0xBB3216E8,0x3DA66446,0xF6FAB7E3, + 0x047A07AD,0xCF26D408,0x49B2A6A6,0x82EE7503,0x9FEB45BB,0x54B7961E,0xD223E4B0,0x197F3715, + 0xE82985C0,0x23755665,0xA5E124CB,0x6EBDF76E,0x73B8C7D6,0xB8E41473,0x3E7066DD,0xF52CB578, + 0x0F580A6C,0xC404D9C9,0x4290AB67,0x89CC78C2,0x94C9487A,0x5F959BDF,0xD901E971,0x125D3AD4, + 0xE30B8801,0x28575BA4,0xAEC3290A,0x659FFAAF,0x789ACA17,0xB3C619B2,0x35526B1C,0xFE0EB8B9, + 0x0C8E08F7,0xC7D2DB52,0x4146A9FC,0x8A1A7A59,0x971F4AE1,0x5C439944,0xDAD7EBEA,0x118B384F, + 0xE0DD8A9A,0x2B81593F,0xAD152B91,0x6649F834,0x7B4CC88C,0xB0101B29,0x36846987,0xFDD8BA22, + 0x08F40F5A,0xC3A8DCFF,0x453CAE51,0x8E607DF4,0x93654D4C,0x58399EE9,0xDEADEC47,0x15F13FE2, + 0xE4A78D37,0x2FFB5E92,0xA96F2C3C,0x6233FF99,0x7F36CF21,0xB46A1C84,0x32FE6E2A,0xF9A2BD8F, + 0x0B220DC1,0xC07EDE64,0x46EAACCA,0x8DB67F6F,0x90B34FD7,0x5BEF9C72,0xDD7BEEDC,0x16273D79, + 0xE7718FAC,0x2C2D5C09,0xAAB92EA7,0x61E5FD02,0x7CE0CDBA,0xB7BC1E1F,0x31286CB1,0xFA74BF14, + 0x1EB014D8,0xD5ECC77D,0x5378B5D3,0x98246676,0x852156CE,0x4E7D856B,0xC8E9F7C5,0x03B52460, + 0xF2E396B5,0x39BF4510,0xBF2B37BE,0x7477E41B,0x6972D4A3,0xA22E0706,0x24BA75A8,0xEFE6A60D, + 0x1D661643,0xD63AC5E6,0x50AEB748,0x9BF264ED,0x86F75455,0x4DAB87F0,0xCB3FF55E,0x006326FB, + 0xF135942E,0x3A69478B,0xBCFD3525,0x77A1E680,0x6AA4D638,0xA1F8059D,0x276C7733,0xEC30A496, + 0x191C11EE,0xD240C24B,0x54D4B0E5,0x9F886340,0x828D53F8,0x49D1805D,0xCF45F2F3,0x04192156, + 0xF54F9383,0x3E134026,0xB8873288,0x73DBE12D,0x6EDED195,0xA5820230,0x2316709E,0xE84AA33B, + 0x1ACA1375,0xD196C0D0,0x5702B27E,0x9C5E61DB,0x815B5163,0x4A0782C6,0xCC93F068,0x07CF23CD, + 0xF6999118,0x3DC542BD,0xBB513013,0x700DE3B6,0x6D08D30E,0xA65400AB,0x20C07205,0xEB9CA1A0, + 0x11E81EB4,0xDAB4CD11,0x5C20BFBF,0x977C6C1A,0x8A795CA2,0x41258F07,0xC7B1FDA9,0x0CED2E0C, + 0xFDBB9CD9,0x36E74F7C,0xB0733DD2,0x7B2FEE77,0x662ADECF,0xAD760D6A,0x2BE27FC4,0xE0BEAC61, + 0x123E1C2F,0xD962CF8A,0x5FF6BD24,0x94AA6E81,0x89AF5E39,0x42F38D9C,0xC467FF32,0x0F3B2C97, + 0xFE6D9E42,0x35314DE7,0xB3A53F49,0x78F9ECEC,0x65FCDC54,0xAEA00FF1,0x28347D5F,0xE368AEFA, + 0x16441B82,0xDD18C827,0x5B8CBA89,0x90D0692C,0x8DD55994,0x46898A31,0xC01DF89F,0x0B412B3A, + 0xFA1799EF,0x314B4A4A,0xB7DF38E4,0x7C83EB41,0x6186DBF9,0xAADA085C,0x2C4E7AF2,0xE712A957, + 0x15921919,0xDECECABC,0x585AB812,0x93066BB7,0x8E035B0F,0x455F88AA,0xC3CBFA04,0x089729A1, + 0xF9C19B74,0x329D48D1,0xB4093A7F,0x7F55E9DA,0x6250D962,0xA90C0AC7,0x2F987869,0xE4C4ABCC, + }, + + { + 0x00000000,0xA6770BB4,0x979F1129,0x31E81A9D,0xF44F2413,0x52382FA7,0x63D0353A,0xC5A73E8E, + 0x33EF4E67,0x959845D3,0xA4705F4E,0x020754FA,0xC7A06A74,0x61D761C0,0x503F7B5D,0xF64870E9, + 0x67DE9CCE,0xC1A9977A,0xF0418DE7,0x56368653,0x9391B8DD,0x35E6B369,0x040EA9F4,0xA279A240, + 0x5431D2A9,0xF246D91D,0xC3AEC380,0x65D9C834,0xA07EF6BA,0x0609FD0E,0x37E1E793,0x9196EC27, + 0xCFBD399C,0x69CA3228,0x582228B5,0xFE552301,0x3BF21D8F,0x9D85163B,0xAC6D0CA6,0x0A1A0712, + 0xFC5277FB,0x5A257C4F,0x6BCD66D2,0xCDBA6D66,0x081D53E8,0xAE6A585C,0x9F8242C1,0x39F54975, + 0xA863A552,0x0E14AEE6,0x3FFCB47B,0x998BBFCF,0x5C2C8141,0xFA5B8AF5,0xCBB39068,0x6DC49BDC, + 0x9B8CEB35,0x3DFBE081,0x0C13FA1C,0xAA64F1A8,0x6FC3CF26,0xC9B4C492,0xF85CDE0F,0x5E2BD5BB, + 0x440B7579,0xE27C7ECD,0xD3946450,0x75E36FE4,0xB044516A,0x16335ADE,0x27DB4043,0x81AC4BF7, + 0x77E43B1E,0xD19330AA,0xE07B2A37,0x460C2183,0x83AB1F0D,0x25DC14B9,0x14340E24,0xB2430590, + 0x23D5E9B7,0x85A2E203,0xB44AF89E,0x123DF32A,0xD79ACDA4,0x71EDC610,0x4005DC8D,0xE672D739, + 0x103AA7D0,0xB64DAC64,0x87A5B6F9,0x21D2BD4D,0xE47583C3,0x42028877,0x73EA92EA,0xD59D995E, + 0x8BB64CE5,0x2DC14751,0x1C295DCC,0xBA5E5678,0x7FF968F6,0xD98E6342,0xE86679DF,0x4E11726B, + 0xB8590282,0x1E2E0936,0x2FC613AB,0x89B1181F,0x4C162691,0xEA612D25,0xDB8937B8,0x7DFE3C0C, + 0xEC68D02B,0x4A1FDB9F,0x7BF7C102,0xDD80CAB6,0x1827F438,0xBE50FF8C,0x8FB8E511,0x29CFEEA5, + 0xDF879E4C,0x79F095F8,0x48188F65,0xEE6F84D1,0x2BC8BA5F,0x8DBFB1EB,0xBC57AB76,0x1A20A0C2, + 0x8816EAF2,0x2E61E146,0x1F89FBDB,0xB9FEF06F,0x7C59CEE1,0xDA2EC555,0xEBC6DFC8,0x4DB1D47C, + 0xBBF9A495,0x1D8EAF21,0x2C66B5BC,0x8A11BE08,0x4FB68086,0xE9C18B32,0xD82991AF,0x7E5E9A1B, + 0xEFC8763C,0x49BF7D88,0x78576715,0xDE206CA1,0x1B87522F,0xBDF0599B,0x8C184306,0x2A6F48B2, + 0xDC27385B,0x7A5033EF,0x4BB82972,0xEDCF22C6,0x28681C48,0x8E1F17FC,0xBFF70D61,0x198006D5, + 0x47ABD36E,0xE1DCD8DA,0xD034C247,0x7643C9F3,0xB3E4F77D,0x1593FCC9,0x247BE654,0x820CEDE0, + 0x74449D09,0xD23396BD,0xE3DB8C20,0x45AC8794,0x800BB91A,0x267CB2AE,0x1794A833,0xB1E3A387, + 0x20754FA0,0x86024414,0xB7EA5E89,0x119D553D,0xD43A6BB3,0x724D6007,0x43A57A9A,0xE5D2712E, + 0x139A01C7,0xB5ED0A73,0x840510EE,0x22721B5A,0xE7D525D4,0x41A22E60,0x704A34FD,0xD63D3F49, + 0xCC1D9F8B,0x6A6A943F,0x5B828EA2,0xFDF58516,0x3852BB98,0x9E25B02C,0xAFCDAAB1,0x09BAA105, + 0xFFF2D1EC,0x5985DA58,0x686DC0C5,0xCE1ACB71,0x0BBDF5FF,0xADCAFE4B,0x9C22E4D6,0x3A55EF62, + 0xABC30345,0x0DB408F1,0x3C5C126C,0x9A2B19D8,0x5F8C2756,0xF9FB2CE2,0xC813367F,0x6E643DCB, + 0x982C4D22,0x3E5B4696,0x0FB35C0B,0xA9C457BF,0x6C636931,0xCA146285,0xFBFC7818,0x5D8B73AC, + 0x03A0A617,0xA5D7ADA3,0x943FB73E,0x3248BC8A,0xF7EF8204,0x519889B0,0x6070932D,0xC6079899, + 0x304FE870,0x9638E3C4,0xA7D0F959,0x01A7F2ED,0xC400CC63,0x6277C7D7,0x539FDD4A,0xF5E8D6FE, + 0x647E3AD9,0xC209316D,0xF3E12BF0,0x55962044,0x90311ECA,0x3646157E,0x07AE0FE3,0xA1D90457, + 0x579174BE,0xF1E67F0A,0xC00E6597,0x66796E23,0xA3DE50AD,0x05A95B19,0x34414184,0x92364A30, + }, + + { + 0x00000000,0xCCAA009E,0x4225077D,0x8E8F07E3,0x844A0EFA,0x48E00E64,0xC66F0987,0x0AC50919, + 0xD3E51BB5,0x1F4F1B2B,0x91C01CC8,0x5D6A1C56,0x57AF154F,0x9B0515D1,0x158A1232,0xD92012AC, + 0x7CBB312B,0xB01131B5,0x3E9E3656,0xF23436C8,0xF8F13FD1,0x345B3F4F,0xBAD438AC,0x767E3832, + 0xAF5E2A9E,0x63F42A00,0xED7B2DE3,0x21D12D7D,0x2B142464,0xE7BE24FA,0x69312319,0xA59B2387, + 0xF9766256,0x35DC62C8,0xBB53652B,0x77F965B5,0x7D3C6CAC,0xB1966C32,0x3F196BD1,0xF3B36B4F, + 0x2A9379E3,0xE639797D,0x68B67E9E,0xA41C7E00,0xAED97719,0x62737787,0xECFC7064,0x205670FA, + 0x85CD537D,0x496753E3,0xC7E85400,0x0B42549E,0x01875D87,0xCD2D5D19,0x43A25AFA,0x8F085A64, + 0x562848C8,0x9A824856,0x140D4FB5,0xD8A74F2B,0xD2624632,0x1EC846AC,0x9047414F,0x5CED41D1, + 0x299DC2ED,0xE537C273,0x6BB8C590,0xA712C50E,0xADD7CC17,0x617DCC89,0xEFF2CB6A,0x2358CBF4, + 0xFA78D958,0x36D2D9C6,0xB85DDE25,0x74F7DEBB,0x7E32D7A2,0xB298D73C,0x3C17D0DF,0xF0BDD041, + 0x5526F3C6,0x998CF358,0x1703F4BB,0xDBA9F425,0xD16CFD3C,0x1DC6FDA2,0x9349FA41,0x5FE3FADF, + 0x86C3E873,0x4A69E8ED,0xC4E6EF0E,0x084CEF90,0x0289E689,0xCE23E617,0x40ACE1F4,0x8C06E16A, + 0xD0EBA0BB,0x1C41A025,0x92CEA7C6,0x5E64A758,0x54A1AE41,0x980BAEDF,0x1684A93C,0xDA2EA9A2, + 0x030EBB0E,0xCFA4BB90,0x412BBC73,0x8D81BCED,0x8744B5F4,0x4BEEB56A,0xC561B289,0x09CBB217, + 0xAC509190,0x60FA910E,0xEE7596ED,0x22DF9673,0x281A9F6A,0xE4B09FF4,0x6A3F9817,0xA6959889, + 0x7FB58A25,0xB31F8ABB,0x3D908D58,0xF13A8DC6,0xFBFF84DF,0x37558441,0xB9DA83A2,0x7570833C, + 0x533B85DA,0x9F918544,0x111E82A7,0xDDB48239,0xD7718B20,0x1BDB8BBE,0x95548C5D,0x59FE8CC3, + 0x80DE9E6F,0x4C749EF1,0xC2FB9912,0x0E51998C,0x04949095,0xC83E900B,0x46B197E8,0x8A1B9776, + 0x2F80B4F1,0xE32AB46F,0x6DA5B38C,0xA10FB312,0xABCABA0B,0x6760BA95,0xE9EFBD76,0x2545BDE8, + 0xFC65AF44,0x30CFAFDA,0xBE40A839,0x72EAA8A7,0x782FA1BE,0xB485A120,0x3A0AA6C3,0xF6A0A65D, + 0xAA4DE78C,0x66E7E712,0xE868E0F1,0x24C2E06F,0x2E07E976,0xE2ADE9E8,0x6C22EE0B,0xA088EE95, + 0x79A8FC39,0xB502FCA7,0x3B8DFB44,0xF727FBDA,0xFDE2F2C3,0x3148F25D,0xBFC7F5BE,0x736DF520, + 0xD6F6D6A7,0x1A5CD639,0x94D3D1DA,0x5879D144,0x52BCD85D,0x9E16D8C3,0x1099DF20,0xDC33DFBE, + 0x0513CD12,0xC9B9CD8C,0x4736CA6F,0x8B9CCAF1,0x8159C3E8,0x4DF3C376,0xC37CC495,0x0FD6C40B, + 0x7AA64737,0xB60C47A9,0x3883404A,0xF42940D4,0xFEEC49CD,0x32464953,0xBCC94EB0,0x70634E2E, + 0xA9435C82,0x65E95C1C,0xEB665BFF,0x27CC5B61,0x2D095278,0xE1A352E6,0x6F2C5505,0xA386559B, + 0x061D761C,0xCAB77682,0x44387161,0x889271FF,0x825778E6,0x4EFD7878,0xC0727F9B,0x0CD87F05, + 0xD5F86DA9,0x19526D37,0x97DD6AD4,0x5B776A4A,0x51B26353,0x9D1863CD,0x1397642E,0xDF3D64B0, + 0x83D02561,0x4F7A25FF,0xC1F5221C,0x0D5F2282,0x079A2B9B,0xCB302B05,0x45BF2CE6,0x89152C78, + 0x50353ED4,0x9C9F3E4A,0x121039A9,0xDEBA3937,0xD47F302E,0x18D530B0,0x965A3753,0x5AF037CD, + 0xFF6B144A,0x33C114D4,0xBD4E1337,0x71E413A9,0x7B211AB0,0xB78B1A2E,0x39041DCD,0xF5AE1D53, + 0x2C8E0FFF,0xE0240F61,0x6EAB0882,0xA201081C,0xA8C40105,0x646E019B,0xEAE10678,0x264B06E6, + } + ,{ + 0x00000000,0x177B1443,0x2EF62886,0x398D3CC5,0x5DEC510C,0x4A97454F,0x731A798A,0x64616DC9, + 0xBBD8A218,0xACA3B65B,0x952E8A9E,0x82559EDD,0xE634F314,0xF14FE757,0xC8C2DB92,0xDFB9CFD1, + 0xACC04271,0xBBBB5632,0x82366AF7,0x954D7EB4,0xF12C137D,0xE657073E,0xDFDA3BFB,0xC8A12FB8, + 0x1718E069,0x0063F42A,0x39EEC8EF,0x2E95DCAC,0x4AF4B165,0x5D8FA526,0x640299E3,0x73798DA0, + 0x82F182A3,0x958A96E0,0xAC07AA25,0xBB7CBE66,0xDF1DD3AF,0xC866C7EC,0xF1EBFB29,0xE690EF6A, + 0x392920BB,0x2E5234F8,0x17DF083D,0x00A41C7E,0x64C571B7,0x73BE65F4,0x4A335931,0x5D484D72, + 0x2E31C0D2,0x394AD491,0x00C7E854,0x17BCFC17,0x73DD91DE,0x64A6859D,0x5D2BB958,0x4A50AD1B, + 0x95E962CA,0x82927689,0xBB1F4A4C,0xAC645E0F,0xC80533C6,0xDF7E2785,0xE6F31B40,0xF1880F03, + 0xDE920307,0xC9E91744,0xF0642B81,0xE71F3FC2,0x837E520B,0x94054648,0xAD887A8D,0xBAF36ECE, + 0x654AA11F,0x7231B55C,0x4BBC8999,0x5CC79DDA,0x38A6F013,0x2FDDE450,0x1650D895,0x012BCCD6, + 0x72524176,0x65295535,0x5CA469F0,0x4BDF7DB3,0x2FBE107A,0x38C50439,0x014838FC,0x16332CBF, + 0xC98AE36E,0xDEF1F72D,0xE77CCBE8,0xF007DFAB,0x9466B262,0x831DA621,0xBA909AE4,0xADEB8EA7, + 0x5C6381A4,0x4B1895E7,0x7295A922,0x65EEBD61,0x018FD0A8,0x16F4C4EB,0x2F79F82E,0x3802EC6D, + 0xE7BB23BC,0xF0C037FF,0xC94D0B3A,0xDE361F79,0xBA5772B0,0xAD2C66F3,0x94A15A36,0x83DA4E75, + 0xF0A3C3D5,0xE7D8D796,0xDE55EB53,0xC92EFF10,0xAD4F92D9,0xBA34869A,0x83B9BA5F,0x94C2AE1C, + 0x4B7B61CD,0x5C00758E,0x658D494B,0x72F65D08,0x169730C1,0x01EC2482,0x38611847,0x2F1A0C04, + 0x6655004F,0x712E140C,0x48A328C9,0x5FD83C8A,0x3BB95143,0x2CC24500,0x154F79C5,0x02346D86, + 0xDD8DA257,0xCAF6B614,0xF37B8AD1,0xE4009E92,0x8061F35B,0x971AE718,0xAE97DBDD,0xB9ECCF9E, + 0xCA95423E,0xDDEE567D,0xE4636AB8,0xF3187EFB,0x97791332,0x80020771,0xB98F3BB4,0xAEF42FF7, + 0x714DE026,0x6636F465,0x5FBBC8A0,0x48C0DCE3,0x2CA1B12A,0x3BDAA569,0x025799AC,0x152C8DEF, + 0xE4A482EC,0xF3DF96AF,0xCA52AA6A,0xDD29BE29,0xB948D3E0,0xAE33C7A3,0x97BEFB66,0x80C5EF25, + 0x5F7C20F4,0x480734B7,0x718A0872,0x66F11C31,0x029071F8,0x15EB65BB,0x2C66597E,0x3B1D4D3D, + 0x4864C09D,0x5F1FD4DE,0x6692E81B,0x71E9FC58,0x15889191,0x02F385D2,0x3B7EB917,0x2C05AD54, + 0xF3BC6285,0xE4C776C6,0xDD4A4A03,0xCA315E40,0xAE503389,0xB92B27CA,0x80A61B0F,0x97DD0F4C, + 0xB8C70348,0xAFBC170B,0x96312BCE,0x814A3F8D,0xE52B5244,0xF2504607,0xCBDD7AC2,0xDCA66E81, + 0x031FA150,0x1464B513,0x2DE989D6,0x3A929D95,0x5EF3F05C,0x4988E41F,0x7005D8DA,0x677ECC99, + 0x14074139,0x037C557A,0x3AF169BF,0x2D8A7DFC,0x49EB1035,0x5E900476,0x671D38B3,0x70662CF0, + 0xAFDFE321,0xB8A4F762,0x8129CBA7,0x9652DFE4,0xF233B22D,0xE548A66E,0xDCC59AAB,0xCBBE8EE8, + 0x3A3681EB,0x2D4D95A8,0x14C0A96D,0x03BBBD2E,0x67DAD0E7,0x70A1C4A4,0x492CF861,0x5E57EC22, + 0x81EE23F3,0x969537B0,0xAF180B75,0xB8631F36,0xDC0272FF,0xCB7966BC,0xF2F45A79,0xE58F4E3A, + 0x96F6C39A,0x818DD7D9,0xB800EB1C,0xAF7BFF5F,0xCB1A9296,0xDC6186D5,0xE5ECBA10,0xF297AE53, + 0x2D2E6182,0x3A5575C1,0x03D84904,0x14A35D47,0x70C2308E,0x67B924CD,0x5E341808,0x494F0C4B, + }, + + { + 0x00000000,0xEFC26B3E,0x04F5D03D,0xEB37BB03,0x09EBA07A,0xE629CB44,0x0D1E7047,0xE2DC1B79, + 0x13D740F4,0xFC152BCA,0x172290C9,0xF8E0FBF7,0x1A3CE08E,0xF5FE8BB0,0x1EC930B3,0xF10B5B8D, + 0x27AE81E8,0xC86CEAD6,0x235B51D5,0xCC993AEB,0x2E452192,0xC1874AAC,0x2AB0F1AF,0xC5729A91, + 0x3479C11C,0xDBBBAA22,0x308C1121,0xDF4E7A1F,0x3D926166,0xD2500A58,0x3967B15B,0xD6A5DA65, + 0x4F5D03D0,0xA09F68EE,0x4BA8D3ED,0xA46AB8D3,0x46B6A3AA,0xA974C894,0x42437397,0xAD8118A9, + 0x5C8A4324,0xB348281A,0x587F9319,0xB7BDF827,0x5561E35E,0xBAA38860,0x51943363,0xBE56585D, + 0x68F38238,0x8731E906,0x6C065205,0x83C4393B,0x61182242,0x8EDA497C,0x65EDF27F,0x8A2F9941, + 0x7B24C2CC,0x94E6A9F2,0x7FD112F1,0x901379CF,0x72CF62B6,0x9D0D0988,0x763AB28B,0x99F8D9B5, + 0x9EBA07A0,0x71786C9E,0x9A4FD79D,0x758DBCA3,0x9751A7DA,0x7893CCE4,0x93A477E7,0x7C661CD9, + 0x8D6D4754,0x62AF2C6A,0x89989769,0x665AFC57,0x8486E72E,0x6B448C10,0x80733713,0x6FB15C2D, + 0xB9148648,0x56D6ED76,0xBDE15675,0x52233D4B,0xB0FF2632,0x5F3D4D0C,0xB40AF60F,0x5BC89D31, + 0xAAC3C6BC,0x4501AD82,0xAE361681,0x41F47DBF,0xA32866C6,0x4CEA0DF8,0xA7DDB6FB,0x481FDDC5, + 0xD1E70470,0x3E256F4E,0xD512D44D,0x3AD0BF73,0xD80CA40A,0x37CECF34,0xDCF97437,0x333B1F09, + 0xC2304484,0x2DF22FBA,0xC6C594B9,0x2907FF87,0xCBDBE4FE,0x24198FC0,0xCF2E34C3,0x20EC5FFD, + 0xF6498598,0x198BEEA6,0xF2BC55A5,0x1D7E3E9B,0xFFA225E2,0x10604EDC,0xFB57F5DF,0x14959EE1, + 0xE59EC56C,0x0A5CAE52,0xE16B1551,0x0EA97E6F,0xEC756516,0x03B70E28,0xE880B52B,0x0742DE15, + 0xE6050901,0x09C7623F,0xE2F0D93C,0x0D32B202,0xEFEEA97B,0x002CC245,0xEB1B7946,0x04D91278, + 0xF5D249F5,0x1A1022CB,0xF12799C8,0x1EE5F2F6,0xFC39E98F,0x13FB82B1,0xF8CC39B2,0x170E528C, + 0xC1AB88E9,0x2E69E3D7,0xC55E58D4,0x2A9C33EA,0xC8402893,0x278243AD,0xCCB5F8AE,0x23779390, + 0xD27CC81D,0x3DBEA323,0xD6891820,0x394B731E,0xDB976867,0x34550359,0xDF62B85A,0x30A0D364, + 0xA9580AD1,0x469A61EF,0xADADDAEC,0x426FB1D2,0xA0B3AAAB,0x4F71C195,0xA4467A96,0x4B8411A8, + 0xBA8F4A25,0x554D211B,0xBE7A9A18,0x51B8F126,0xB364EA5F,0x5CA68161,0xB7913A62,0x5853515C, + 0x8EF68B39,0x6134E007,0x8A035B04,0x65C1303A,0x871D2B43,0x68DF407D,0x83E8FB7E,0x6C2A9040, + 0x9D21CBCD,0x72E3A0F3,0x99D41BF0,0x761670CE,0x94CA6BB7,0x7B080089,0x903FBB8A,0x7FFDD0B4, + 0x78BF0EA1,0x977D659F,0x7C4ADE9C,0x9388B5A2,0x7154AEDB,0x9E96C5E5,0x75A17EE6,0x9A6315D8, + 0x6B684E55,0x84AA256B,0x6F9D9E68,0x805FF556,0x6283EE2F,0x8D418511,0x66763E12,0x89B4552C, + 0x5F118F49,0xB0D3E477,0x5BE45F74,0xB426344A,0x56FA2F33,0xB938440D,0x520FFF0E,0xBDCD9430, + 0x4CC6CFBD,0xA304A483,0x48331F80,0xA7F174BE,0x452D6FC7,0xAAEF04F9,0x41D8BFFA,0xAE1AD4C4, + 0x37E20D71,0xD820664F,0x3317DD4C,0xDCD5B672,0x3E09AD0B,0xD1CBC635,0x3AFC7D36,0xD53E1608, + 0x24354D85,0xCBF726BB,0x20C09DB8,0xCF02F686,0x2DDEEDFF,0xC21C86C1,0x292B3DC2,0xC6E956FC, + 0x104C8C99,0xFF8EE7A7,0x14B95CA4,0xFB7B379A,0x19A72CE3,0xF66547DD,0x1D52FCDE,0xF29097E0, + 0x039BCC6D,0xEC59A753,0x076E1C50,0xE8AC776E,0x0A706C17,0xE5B20729,0x0E85BC2A,0xE147D714, + }, + + { + 0x00000000,0xC18EDFC0,0x586CB9C1,0x99E26601,0xB0D97382,0x7157AC42,0xE8B5CA43,0x293B1583, + 0xBAC3E145,0x7B4D3E85,0xE2AF5884,0x23218744,0x0A1A92C7,0xCB944D07,0x52762B06,0x93F8F4C6, + 0xAEF6C4CB,0x6F781B0B,0xF69A7D0A,0x3714A2CA,0x1E2FB749,0xDFA16889,0x46430E88,0x87CDD148, + 0x1435258E,0xD5BBFA4E,0x4C599C4F,0x8DD7438F,0xA4EC560C,0x656289CC,0xFC80EFCD,0x3D0E300D, + 0x869C8FD7,0x47125017,0xDEF03616,0x1F7EE9D6,0x3645FC55,0xF7CB2395,0x6E294594,0xAFA79A54, + 0x3C5F6E92,0xFDD1B152,0x6433D753,0xA5BD0893,0x8C861D10,0x4D08C2D0,0xD4EAA4D1,0x15647B11, + 0x286A4B1C,0xE9E494DC,0x7006F2DD,0xB1882D1D,0x98B3389E,0x593DE75E,0xC0DF815F,0x01515E9F, + 0x92A9AA59,0x53277599,0xCAC51398,0x0B4BCC58,0x2270D9DB,0xE3FE061B,0x7A1C601A,0xBB92BFDA, + 0xD64819EF,0x17C6C62F,0x8E24A02E,0x4FAA7FEE,0x66916A6D,0xA71FB5AD,0x3EFDD3AC,0xFF730C6C, + 0x6C8BF8AA,0xAD05276A,0x34E7416B,0xF5699EAB,0xDC528B28,0x1DDC54E8,0x843E32E9,0x45B0ED29, + 0x78BEDD24,0xB93002E4,0x20D264E5,0xE15CBB25,0xC867AEA6,0x09E97166,0x900B1767,0x5185C8A7, + 0xC27D3C61,0x03F3E3A1,0x9A1185A0,0x5B9F5A60,0x72A44FE3,0xB32A9023,0x2AC8F622,0xEB4629E2, + 0x50D49638,0x915A49F8,0x08B82FF9,0xC936F039,0xE00DE5BA,0x21833A7A,0xB8615C7B,0x79EF83BB, + 0xEA17777D,0x2B99A8BD,0xB27BCEBC,0x73F5117C,0x5ACE04FF,0x9B40DB3F,0x02A2BD3E,0xC32C62FE, + 0xFE2252F3,0x3FAC8D33,0xA64EEB32,0x67C034F2,0x4EFB2171,0x8F75FEB1,0x169798B0,0xD7194770, + 0x44E1B3B6,0x856F6C76,0x1C8D0A77,0xDD03D5B7,0xF438C034,0x35B61FF4,0xAC5479F5,0x6DDAA635, + 0x77E1359F,0xB66FEA5F,0x2F8D8C5E,0xEE03539E,0xC738461D,0x06B699DD,0x9F54FFDC,0x5EDA201C, + 0xCD22D4DA,0x0CAC0B1A,0x954E6D1B,0x54C0B2DB,0x7DFBA758,0xBC757898,0x25971E99,0xE419C159, + 0xD917F154,0x18992E94,0x817B4895,0x40F59755,0x69CE82D6,0xA8405D16,0x31A23B17,0xF02CE4D7, + 0x63D41011,0xA25ACFD1,0x3BB8A9D0,0xFA367610,0xD30D6393,0x1283BC53,0x8B61DA52,0x4AEF0592, + 0xF17DBA48,0x30F36588,0xA9110389,0x689FDC49,0x41A4C9CA,0x802A160A,0x19C8700B,0xD846AFCB, + 0x4BBE5B0D,0x8A3084CD,0x13D2E2CC,0xD25C3D0C,0xFB67288F,0x3AE9F74F,0xA30B914E,0x62854E8E, + 0x5F8B7E83,0x9E05A143,0x07E7C742,0xC6691882,0xEF520D01,0x2EDCD2C1,0xB73EB4C0,0x76B06B00, + 0xE5489FC6,0x24C64006,0xBD242607,0x7CAAF9C7,0x5591EC44,0x941F3384,0x0DFD5585,0xCC738A45, + 0xA1A92C70,0x6027F3B0,0xF9C595B1,0x384B4A71,0x11705FF2,0xD0FE8032,0x491CE633,0x889239F3, + 0x1B6ACD35,0xDAE412F5,0x430674F4,0x8288AB34,0xABB3BEB7,0x6A3D6177,0xF3DF0776,0x3251D8B6, + 0x0F5FE8BB,0xCED1377B,0x5733517A,0x96BD8EBA,0xBF869B39,0x7E0844F9,0xE7EA22F8,0x2664FD38, + 0xB59C09FE,0x7412D63E,0xEDF0B03F,0x2C7E6FFF,0x05457A7C,0xC4CBA5BC,0x5D29C3BD,0x9CA71C7D, + 0x2735A3A7,0xE6BB7C67,0x7F591A66,0xBED7C5A6,0x97ECD025,0x56620FE5,0xCF8069E4,0x0E0EB624, + 0x9DF642E2,0x5C789D22,0xC59AFB23,0x041424E3,0x2D2F3160,0xECA1EEA0,0x754388A1,0xB4CD5761, + 0x89C3676C,0x484DB8AC,0xD1AFDEAD,0x1021016D,0x391A14EE,0xF894CB2E,0x6176AD2F,0xA0F872EF, + 0x33008629,0xF28E59E9,0x6B6C3FE8,0xAAE2E028,0x83D9F5AB,0x42572A6B,0xDBB54C6A,0x1A3B93AA, + }, + + { + 0x00000000,0x9BA54C6F,0xEC3B9E9F,0x779ED2F0,0x03063B7F,0x98A37710,0xEF3DA5E0,0x7498E98F, + 0x060C76FE,0x9DA93A91,0xEA37E861,0x7192A40E,0x050A4D81,0x9EAF01EE,0xE931D31E,0x72949F71, + 0x0C18EDFC,0x97BDA193,0xE0237363,0x7B863F0C,0x0F1ED683,0x94BB9AEC,0xE325481C,0x78800473, + 0x0A149B02,0x91B1D76D,0xE62F059D,0x7D8A49F2,0x0912A07D,0x92B7EC12,0xE5293EE2,0x7E8C728D, + 0x1831DBF8,0x83949797,0xF40A4567,0x6FAF0908,0x1B37E087,0x8092ACE8,0xF70C7E18,0x6CA93277, + 0x1E3DAD06,0x8598E169,0xF2063399,0x69A37FF6,0x1D3B9679,0x869EDA16,0xF10008E6,0x6AA54489, + 0x14293604,0x8F8C7A6B,0xF812A89B,0x63B7E4F4,0x172F0D7B,0x8C8A4114,0xFB1493E4,0x60B1DF8B, + 0x122540FA,0x89800C95,0xFE1EDE65,0x65BB920A,0x11237B85,0x8A8637EA,0xFD18E51A,0x66BDA975, + 0x3063B7F0,0xABC6FB9F,0xDC58296F,0x47FD6500,0x33658C8F,0xA8C0C0E0,0xDF5E1210,0x44FB5E7F, + 0x366FC10E,0xADCA8D61,0xDA545F91,0x41F113FE,0x3569FA71,0xAECCB61E,0xD95264EE,0x42F72881, + 0x3C7B5A0C,0xA7DE1663,0xD040C493,0x4BE588FC,0x3F7D6173,0xA4D82D1C,0xD346FFEC,0x48E3B383, + 0x3A772CF2,0xA1D2609D,0xD64CB26D,0x4DE9FE02,0x3971178D,0xA2D45BE2,0xD54A8912,0x4EEFC57D, + 0x28526C08,0xB3F72067,0xC469F297,0x5FCCBEF8,0x2B545777,0xB0F11B18,0xC76FC9E8,0x5CCA8587, + 0x2E5E1AF6,0xB5FB5699,0xC2658469,0x59C0C806,0x2D582189,0xB6FD6DE6,0xC163BF16,0x5AC6F379, + 0x244A81F4,0xBFEFCD9B,0xC8711F6B,0x53D45304,0x274CBA8B,0xBCE9F6E4,0xCB772414,0x50D2687B, + 0x2246F70A,0xB9E3BB65,0xCE7D6995,0x55D825FA,0x2140CC75,0xBAE5801A,0xCD7B52EA,0x56DE1E85, + 0x60C76FE0,0xFB62238F,0x8CFCF17F,0x1759BD10,0x63C1549F,0xF86418F0,0x8FFACA00,0x145F866F, + 0x66CB191E,0xFD6E5571,0x8AF08781,0x1155CBEE,0x65CD2261,0xFE686E0E,0x89F6BCFE,0x1253F091, + 0x6CDF821C,0xF77ACE73,0x80E41C83,0x1B4150EC,0x6FD9B963,0xF47CF50C,0x83E227FC,0x18476B93, + 0x6AD3F4E2,0xF176B88D,0x86E86A7D,0x1D4D2612,0x69D5CF9D,0xF27083F2,0x85EE5102,0x1E4B1D6D, + 0x78F6B418,0xE353F877,0x94CD2A87,0x0F6866E8,0x7BF08F67,0xE055C308,0x97CB11F8,0x0C6E5D97, + 0x7EFAC2E6,0xE55F8E89,0x92C15C79,0x09641016,0x7DFCF999,0xE659B5F6,0x91C76706,0x0A622B69, + 0x74EE59E4,0xEF4B158B,0x98D5C77B,0x03708B14,0x77E8629B,0xEC4D2EF4,0x9BD3FC04,0x0076B06B, + 0x72E22F1A,0xE9476375,0x9ED9B185,0x057CFDEA,0x71E41465,0xEA41580A,0x9DDF8AFA,0x067AC695, + 0x50A4D810,0xCB01947F,0xBC9F468F,0x273A0AE0,0x53A2E36F,0xC807AF00,0xBF997DF0,0x243C319F, + 0x56A8AEEE,0xCD0DE281,0xBA933071,0x21367C1E,0x55AE9591,0xCE0BD9FE,0xB9950B0E,0x22304761, + 0x5CBC35EC,0xC7197983,0xB087AB73,0x2B22E71C,0x5FBA0E93,0xC41F42FC,0xB381900C,0x2824DC63, + 0x5AB04312,0xC1150F7D,0xB68BDD8D,0x2D2E91E2,0x59B6786D,0xC2133402,0xB58DE6F2,0x2E28AA9D, + 0x489503E8,0xD3304F87,0xA4AE9D77,0x3F0BD118,0x4B933897,0xD03674F8,0xA7A8A608,0x3C0DEA67, + 0x4E997516,0xD53C3979,0xA2A2EB89,0x3907A7E6,0x4D9F4E69,0xD63A0206,0xA1A4D0F6,0x3A019C99, + 0x448DEE14,0xDF28A27B,0xA8B6708B,0x33133CE4,0x478BD56B,0xDC2E9904,0xABB04BF4,0x3015079B, + 0x428198EA,0xD924D485,0xAEBA0675,0x351F4A1A,0x4187A395,0xDA22EFFA,0xADBC3D0A,0x36197165, + }, + + { + 0x00000000,0xDD96D985,0x605CB54B,0xBDCA6CCE,0xC0B96A96,0x1D2FB313,0xA0E5DFDD,0x7D730658, + 0x5A03D36D,0x87950AE8,0x3A5F6626,0xE7C9BFA3,0x9ABAB9FB,0x472C607E,0xFAE60CB0,0x2770D535, + 0xB407A6DA,0x69917F5F,0xD45B1391,0x09CDCA14,0x74BECC4C,0xA92815C9,0x14E27907,0xC974A082, + 0xEE0475B7,0x3392AC32,0x8E58C0FC,0x53CE1979,0x2EBD1F21,0xF32BC6A4,0x4EE1AA6A,0x937773EF, + 0xB37E4BF5,0x6EE89270,0xD322FEBE,0x0EB4273B,0x73C72163,0xAE51F8E6,0x139B9428,0xCE0D4DAD, + 0xE97D9898,0x34EB411D,0x89212DD3,0x54B7F456,0x29C4F20E,0xF4522B8B,0x49984745,0x940E9EC0, + 0x0779ED2F,0xDAEF34AA,0x67255864,0xBAB381E1,0xC7C087B9,0x1A565E3C,0xA79C32F2,0x7A0AEB77, + 0x5D7A3E42,0x80ECE7C7,0x3D268B09,0xE0B0528C,0x9DC354D4,0x40558D51,0xFD9FE19F,0x2009381A, + 0xBD8D91AB,0x601B482E,0xDDD124E0,0x0047FD65,0x7D34FB3D,0xA0A222B8,0x1D684E76,0xC0FE97F3, + 0xE78E42C6,0x3A189B43,0x87D2F78D,0x5A442E08,0x27372850,0xFAA1F1D5,0x476B9D1B,0x9AFD449E, + 0x098A3771,0xD41CEEF4,0x69D6823A,0xB4405BBF,0xC9335DE7,0x14A58462,0xA96FE8AC,0x74F93129, + 0x5389E41C,0x8E1F3D99,0x33D55157,0xEE4388D2,0x93308E8A,0x4EA6570F,0xF36C3BC1,0x2EFAE244, + 0x0EF3DA5E,0xD36503DB,0x6EAF6F15,0xB339B690,0xCE4AB0C8,0x13DC694D,0xAE160583,0x7380DC06, + 0x54F00933,0x8966D0B6,0x34ACBC78,0xE93A65FD,0x944963A5,0x49DFBA20,0xF415D6EE,0x29830F6B, + 0xBAF47C84,0x6762A501,0xDAA8C9CF,0x073E104A,0x7A4D1612,0xA7DBCF97,0x1A11A359,0xC7877ADC, + 0xE0F7AFE9,0x3D61766C,0x80AB1AA2,0x5D3DC327,0x204EC57F,0xFDD81CFA,0x40127034,0x9D84A9B1, + 0xA06A2517,0x7DFCFC92,0xC036905C,0x1DA049D9,0x60D34F81,0xBD459604,0x008FFACA,0xDD19234F, + 0xFA69F67A,0x27FF2FFF,0x9A354331,0x47A39AB4,0x3AD09CEC,0xE7464569,0x5A8C29A7,0x871AF022, + 0x146D83CD,0xC9FB5A48,0x74313686,0xA9A7EF03,0xD4D4E95B,0x094230DE,0xB4885C10,0x691E8595, + 0x4E6E50A0,0x93F88925,0x2E32E5EB,0xF3A43C6E,0x8ED73A36,0x5341E3B3,0xEE8B8F7D,0x331D56F8, + 0x13146EE2,0xCE82B767,0x7348DBA9,0xAEDE022C,0xD3AD0474,0x0E3BDDF1,0xB3F1B13F,0x6E6768BA, + 0x4917BD8F,0x9481640A,0x294B08C4,0xF4DDD141,0x89AED719,0x54380E9C,0xE9F26252,0x3464BBD7, + 0xA713C838,0x7A8511BD,0xC74F7D73,0x1AD9A4F6,0x67AAA2AE,0xBA3C7B2B,0x07F617E5,0xDA60CE60, + 0xFD101B55,0x2086C2D0,0x9D4CAE1E,0x40DA779B,0x3DA971C3,0xE03FA846,0x5DF5C488,0x80631D0D, + 0x1DE7B4BC,0xC0716D39,0x7DBB01F7,0xA02DD872,0xDD5EDE2A,0x00C807AF,0xBD026B61,0x6094B2E4, + 0x47E467D1,0x9A72BE54,0x27B8D29A,0xFA2E0B1F,0x875D0D47,0x5ACBD4C2,0xE701B80C,0x3A976189, + 0xA9E01266,0x7476CBE3,0xC9BCA72D,0x142A7EA8,0x695978F0,0xB4CFA175,0x0905CDBB,0xD493143E, + 0xF3E3C10B,0x2E75188E,0x93BF7440,0x4E29ADC5,0x335AAB9D,0xEECC7218,0x53061ED6,0x8E90C753, + 0xAE99FF49,0x730F26CC,0xCEC54A02,0x13539387,0x6E2095DF,0xB3B64C5A,0x0E7C2094,0xD3EAF911, + 0xF49A2C24,0x290CF5A1,0x94C6996F,0x495040EA,0x342346B2,0xE9B59F37,0x547FF3F9,0x89E92A7C, + 0x1A9E5993,0xC7088016,0x7AC2ECD8,0xA754355D,0xDA273305,0x07B1EA80,0xBA7B864E,0x67ED5FCB, + 0x409D8AFE,0x9D0B537B,0x20C13FB5,0xFD57E630,0x8024E068,0x5DB239ED,0xE0785523,0x3DEE8CA6, + }, + + { + 0x00000000,0x9D0FE176,0xE16EC4AD,0x7C6125DB,0x19AC8F1B,0x84A36E6D,0xF8C24BB6,0x65CDAAC0, + 0x33591E36,0xAE56FF40,0xD237DA9B,0x4F383BED,0x2AF5912D,0xB7FA705B,0xCB9B5580,0x5694B4F6, + 0x66B23C6C,0xFBBDDD1A,0x87DCF8C1,0x1AD319B7,0x7F1EB377,0xE2115201,0x9E7077DA,0x037F96AC, + 0x55EB225A,0xC8E4C32C,0xB485E6F7,0x298A0781,0x4C47AD41,0xD1484C37,0xAD2969EC,0x3026889A, + 0xCD6478D8,0x506B99AE,0x2C0ABC75,0xB1055D03,0xD4C8F7C3,0x49C716B5,0x35A6336E,0xA8A9D218, + 0xFE3D66EE,0x63328798,0x1F53A243,0x825C4335,0xE791E9F5,0x7A9E0883,0x06FF2D58,0x9BF0CC2E, + 0xABD644B4,0x36D9A5C2,0x4AB88019,0xD7B7616F,0xB27ACBAF,0x2F752AD9,0x53140F02,0xCE1BEE74, + 0x988F5A82,0x0580BBF4,0x79E19E2F,0xE4EE7F59,0x8123D599,0x1C2C34EF,0x604D1134,0xFD42F042, + 0x41B9F7F1,0xDCB61687,0xA0D7335C,0x3DD8D22A,0x581578EA,0xC51A999C,0xB97BBC47,0x24745D31, + 0x72E0E9C7,0xEFEF08B1,0x938E2D6A,0x0E81CC1C,0x6B4C66DC,0xF64387AA,0x8A22A271,0x172D4307, + 0x270BCB9D,0xBA042AEB,0xC6650F30,0x5B6AEE46,0x3EA74486,0xA3A8A5F0,0xDFC9802B,0x42C6615D, + 0x1452D5AB,0x895D34DD,0xF53C1106,0x6833F070,0x0DFE5AB0,0x90F1BBC6,0xEC909E1D,0x719F7F6B, + 0x8CDD8F29,0x11D26E5F,0x6DB34B84,0xF0BCAAF2,0x95710032,0x087EE144,0x741FC49F,0xE91025E9, + 0xBF84911F,0x228B7069,0x5EEA55B2,0xC3E5B4C4,0xA6281E04,0x3B27FF72,0x4746DAA9,0xDA493BDF, + 0xEA6FB345,0x77605233,0x0B0177E8,0x960E969E,0xF3C33C5E,0x6ECCDD28,0x12ADF8F3,0x8FA21985, + 0xD936AD73,0x44394C05,0x385869DE,0xA55788A8,0xC09A2268,0x5D95C31E,0x21F4E6C5,0xBCFB07B3, + 0x8373EFE2,0x1E7C0E94,0x621D2B4F,0xFF12CA39,0x9ADF60F9,0x07D0818F,0x7BB1A454,0xE6BE4522, + 0xB02AF1D4,0x2D2510A2,0x51443579,0xCC4BD40F,0xA9867ECF,0x34899FB9,0x48E8BA62,0xD5E75B14, + 0xE5C1D38E,0x78CE32F8,0x04AF1723,0x99A0F655,0xFC6D5C95,0x6162BDE3,0x1D039838,0x800C794E, + 0xD698CDB8,0x4B972CCE,0x37F60915,0xAAF9E863,0xCF3442A3,0x523BA3D5,0x2E5A860E,0xB3556778, + 0x4E17973A,0xD318764C,0xAF795397,0x3276B2E1,0x57BB1821,0xCAB4F957,0xB6D5DC8C,0x2BDA3DFA, + 0x7D4E890C,0xE041687A,0x9C204DA1,0x012FACD7,0x64E20617,0xF9EDE761,0x858CC2BA,0x188323CC, + 0x28A5AB56,0xB5AA4A20,0xC9CB6FFB,0x54C48E8D,0x3109244D,0xAC06C53B,0xD067E0E0,0x4D680196, + 0x1BFCB560,0x86F35416,0xFA9271CD,0x679D90BB,0x02503A7B,0x9F5FDB0D,0xE33EFED6,0x7E311FA0, + 0xC2CA1813,0x5FC5F965,0x23A4DCBE,0xBEAB3DC8,0xDB669708,0x4669767E,0x3A0853A5,0xA707B2D3, + 0xF1930625,0x6C9CE753,0x10FDC288,0x8DF223FE,0xE83F893E,0x75306848,0x09514D93,0x945EACE5, + 0xA478247F,0x3977C509,0x4516E0D2,0xD81901A4,0xBDD4AB64,0x20DB4A12,0x5CBA6FC9,0xC1B58EBF, + 0x97213A49,0x0A2EDB3F,0x764FFEE4,0xEB401F92,0x8E8DB552,0x13825424,0x6FE371FF,0xF2EC9089, + 0x0FAE60CB,0x92A181BD,0xEEC0A466,0x73CF4510,0x1602EFD0,0x8B0D0EA6,0xF76C2B7D,0x6A63CA0B, + 0x3CF77EFD,0xA1F89F8B,0xDD99BA50,0x40965B26,0x255BF1E6,0xB8541090,0xC435354B,0x593AD43D, + 0x691C5CA7,0xF413BDD1,0x8872980A,0x157D797C,0x70B0D3BC,0xEDBF32CA,0x91DE1711,0x0CD1F667, + 0x5A454291,0xC74AA3E7,0xBB2B863C,0x2624674A,0x43E9CD8A,0xDEE62CFC,0xA2870927,0x3F88E851, + }, + + { + 0x00000000,0xB9FBDBE8,0xA886B191,0x117D6A79,0x8A7C6563,0x3387BE8B,0x22FAD4F2,0x9B010F1A, + 0xCF89CC87,0x7672176F,0x670F7D16,0xDEF4A6FE,0x45F5A9E4,0xFC0E720C,0xED731875,0x5488C39D, + 0x44629F4F,0xFD9944A7,0xECE42EDE,0x551FF536,0xCE1EFA2C,0x77E521C4,0x66984BBD,0xDF639055, + 0x8BEB53C8,0x32108820,0x236DE259,0x9A9639B1,0x019736AB,0xB86CED43,0xA911873A,0x10EA5CD2, + 0x88C53E9E,0x313EE576,0x20438F0F,0x99B854E7,0x02B95BFD,0xBB428015,0xAA3FEA6C,0x13C43184, + 0x474CF219,0xFEB729F1,0xEFCA4388,0x56319860,0xCD30977A,0x74CB4C92,0x65B626EB,0xDC4DFD03, + 0xCCA7A1D1,0x755C7A39,0x64211040,0xDDDACBA8,0x46DBC4B2,0xFF201F5A,0xEE5D7523,0x57A6AECB, + 0x032E6D56,0xBAD5B6BE,0xABA8DCC7,0x1253072F,0x89520835,0x30A9D3DD,0x21D4B9A4,0x982F624C, + 0xCAFB7B7D,0x7300A095,0x627DCAEC,0xDB861104,0x40871E1E,0xF97CC5F6,0xE801AF8F,0x51FA7467, + 0x0572B7FA,0xBC896C12,0xADF4066B,0x140FDD83,0x8F0ED299,0x36F50971,0x27886308,0x9E73B8E0, + 0x8E99E432,0x37623FDA,0x261F55A3,0x9FE48E4B,0x04E58151,0xBD1E5AB9,0xAC6330C0,0x1598EB28, + 0x411028B5,0xF8EBF35D,0xE9969924,0x506D42CC,0xCB6C4DD6,0x7297963E,0x63EAFC47,0xDA1127AF, + 0x423E45E3,0xFBC59E0B,0xEAB8F472,0x53432F9A,0xC8422080,0x71B9FB68,0x60C49111,0xD93F4AF9, + 0x8DB78964,0x344C528C,0x253138F5,0x9CCAE31D,0x07CBEC07,0xBE3037EF,0xAF4D5D96,0x16B6867E, + 0x065CDAAC,0xBFA70144,0xAEDA6B3D,0x1721B0D5,0x8C20BFCF,0x35DB6427,0x24A60E5E,0x9D5DD5B6, + 0xC9D5162B,0x702ECDC3,0x6153A7BA,0xD8A87C52,0x43A97348,0xFA52A8A0,0xEB2FC2D9,0x52D41931, + 0x4E87F0BB,0xF77C2B53,0xE601412A,0x5FFA9AC2,0xC4FB95D8,0x7D004E30,0x6C7D2449,0xD586FFA1, + 0x810E3C3C,0x38F5E7D4,0x29888DAD,0x90735645,0x0B72595F,0xB28982B7,0xA3F4E8CE,0x1A0F3326, + 0x0AE56FF4,0xB31EB41C,0xA263DE65,0x1B98058D,0x80990A97,0x3962D17F,0x281FBB06,0x91E460EE, + 0xC56CA373,0x7C97789B,0x6DEA12E2,0xD411C90A,0x4F10C610,0xF6EB1DF8,0xE7967781,0x5E6DAC69, + 0xC642CE25,0x7FB915CD,0x6EC47FB4,0xD73FA45C,0x4C3EAB46,0xF5C570AE,0xE4B81AD7,0x5D43C13F, + 0x09CB02A2,0xB030D94A,0xA14DB333,0x18B668DB,0x83B767C1,0x3A4CBC29,0x2B31D650,0x92CA0DB8, + 0x8220516A,0x3BDB8A82,0x2AA6E0FB,0x935D3B13,0x085C3409,0xB1A7EFE1,0xA0DA8598,0x19215E70, + 0x4DA99DED,0xF4524605,0xE52F2C7C,0x5CD4F794,0xC7D5F88E,0x7E2E2366,0x6F53491F,0xD6A892F7, + 0x847C8BC6,0x3D87502E,0x2CFA3A57,0x9501E1BF,0x0E00EEA5,0xB7FB354D,0xA6865F34,0x1F7D84DC, + 0x4BF54741,0xF20E9CA9,0xE373F6D0,0x5A882D38,0xC1892222,0x7872F9CA,0x690F93B3,0xD0F4485B, + 0xC01E1489,0x79E5CF61,0x6898A518,0xD1637EF0,0x4A6271EA,0xF399AA02,0xE2E4C07B,0x5B1F1B93, + 0x0F97D80E,0xB66C03E6,0xA711699F,0x1EEAB277,0x85EBBD6D,0x3C106685,0x2D6D0CFC,0x9496D714, + 0x0CB9B558,0xB5426EB0,0xA43F04C9,0x1DC4DF21,0x86C5D03B,0x3F3E0BD3,0x2E4361AA,0x97B8BA42, + 0xC33079DF,0x7ACBA237,0x6BB6C84E,0xD24D13A6,0x494C1CBC,0xF0B7C754,0xE1CAAD2D,0x583176C5, + 0x48DB2A17,0xF120F1FF,0xE05D9B86,0x59A6406E,0xC2A74F74,0x7B5C949C,0x6A21FEE5,0xD3DA250D, + 0x8752E690,0x3EA93D78,0x2FD45701,0x962F8CE9,0x0D2E83F3,0xB4D5581B,0xA5A83262,0x1C53E98A, + }, + + { + 0x00000000,0xAE689191,0x87A02563,0x29C8B4F2,0xD4314C87,0x7A59DD16,0x539169E4,0xFDF9F875, + 0x73139F4F,0xDD7B0EDE,0xF4B3BA2C,0x5ADB2BBD,0xA722D3C8,0x094A4259,0x2082F6AB,0x8EEA673A, + 0xE6273E9E,0x484FAF0F,0x61871BFD,0xCFEF8A6C,0x32167219,0x9C7EE388,0xB5B6577A,0x1BDEC6EB, + 0x9534A1D1,0x3B5C3040,0x129484B2,0xBCFC1523,0x4105ED56,0xEF6D7CC7,0xC6A5C835,0x68CD59A4, + 0x173F7B7D,0xB957EAEC,0x909F5E1E,0x3EF7CF8F,0xC30E37FA,0x6D66A66B,0x44AE1299,0xEAC68308, + 0x642CE432,0xCA4475A3,0xE38CC151,0x4DE450C0,0xB01DA8B5,0x1E753924,0x37BD8DD6,0x99D51C47, + 0xF11845E3,0x5F70D472,0x76B86080,0xD8D0F111,0x25290964,0x8B4198F5,0xA2892C07,0x0CE1BD96, + 0x820BDAAC,0x2C634B3D,0x05ABFFCF,0xABC36E5E,0x563A962B,0xF85207BA,0xD19AB348,0x7FF222D9, + 0x2E7EF6FA,0x8016676B,0xA9DED399,0x07B64208,0xFA4FBA7D,0x54272BEC,0x7DEF9F1E,0xD3870E8F, + 0x5D6D69B5,0xF305F824,0xDACD4CD6,0x74A5DD47,0x895C2532,0x2734B4A3,0x0EFC0051,0xA09491C0, + 0xC859C864,0x663159F5,0x4FF9ED07,0xE1917C96,0x1C6884E3,0xB2001572,0x9BC8A180,0x35A03011, + 0xBB4A572B,0x1522C6BA,0x3CEA7248,0x9282E3D9,0x6F7B1BAC,0xC1138A3D,0xE8DB3ECF,0x46B3AF5E, + 0x39418D87,0x97291C16,0xBEE1A8E4,0x10893975,0xED70C100,0x43185091,0x6AD0E463,0xC4B875F2, + 0x4A5212C8,0xE43A8359,0xCDF237AB,0x639AA63A,0x9E635E4F,0x300BCFDE,0x19C37B2C,0xB7ABEABD, + 0xDF66B319,0x710E2288,0x58C6967A,0xF6AE07EB,0x0B57FF9E,0xA53F6E0F,0x8CF7DAFD,0x229F4B6C, + 0xAC752C56,0x021DBDC7,0x2BD50935,0x85BD98A4,0x784460D1,0xD62CF140,0xFFE445B2,0x518CD423, + 0x5CFDEDF4,0xF2957C65,0xDB5DC897,0x75355906,0x88CCA173,0x26A430E2,0x0F6C8410,0xA1041581, + 0x2FEE72BB,0x8186E32A,0xA84E57D8,0x0626C649,0xFBDF3E3C,0x55B7AFAD,0x7C7F1B5F,0xD2178ACE, + 0xBADAD36A,0x14B242FB,0x3D7AF609,0x93126798,0x6EEB9FED,0xC0830E7C,0xE94BBA8E,0x47232B1F, + 0xC9C94C25,0x67A1DDB4,0x4E696946,0xE001F8D7,0x1DF800A2,0xB3909133,0x9A5825C1,0x3430B450, + 0x4BC29689,0xE5AA0718,0xCC62B3EA,0x620A227B,0x9FF3DA0E,0x319B4B9F,0x1853FF6D,0xB63B6EFC, + 0x38D109C6,0x96B99857,0xBF712CA5,0x1119BD34,0xECE04541,0x4288D4D0,0x6B406022,0xC528F1B3, + 0xADE5A817,0x038D3986,0x2A458D74,0x842D1CE5,0x79D4E490,0xD7BC7501,0xFE74C1F3,0x501C5062, + 0xDEF63758,0x709EA6C9,0x5956123B,0xF73E83AA,0x0AC77BDF,0xA4AFEA4E,0x8D675EBC,0x230FCF2D, + 0x72831B0E,0xDCEB8A9F,0xF5233E6D,0x5B4BAFFC,0xA6B25789,0x08DAC618,0x211272EA,0x8F7AE37B, + 0x01908441,0xAFF815D0,0x8630A122,0x285830B3,0xD5A1C8C6,0x7BC95957,0x5201EDA5,0xFC697C34, + 0x94A42590,0x3ACCB401,0x130400F3,0xBD6C9162,0x40956917,0xEEFDF886,0xC7354C74,0x695DDDE5, + 0xE7B7BADF,0x49DF2B4E,0x60179FBC,0xCE7F0E2D,0x3386F658,0x9DEE67C9,0xB426D33B,0x1A4E42AA, + 0x65BC6073,0xCBD4F1E2,0xE21C4510,0x4C74D481,0xB18D2CF4,0x1FE5BD65,0x362D0997,0x98459806, + 0x16AFFF3C,0xB8C76EAD,0x910FDA5F,0x3F674BCE,0xC29EB3BB,0x6CF6222A,0x453E96D8,0xEB560749, + 0x839B5EED,0x2DF3CF7C,0x043B7B8E,0xAA53EA1F,0x57AA126A,0xF9C283FB,0xD00A3709,0x7E62A698, + 0xF088C1A2,0x5EE05033,0x7728E4C1,0xD9407550,0x24B98D25,0x8AD11CB4,0xA319A846,0x0D7139D7, + } +}; \ No newline at end of file diff --git a/Utilities/CRC32.h b/Utilities/CRC32.h index 836f1a46..fa79eef1 100644 --- a/Utilities/CRC32.h +++ b/Utilities/CRC32.h @@ -1,81 +1,10 @@ -//From: http://tdistler.com/2011/06/22/crc32-a-simple-c-class -//"You are free to use and adapt this code however you likec that goes for anyone." #pragma once #include "stdafx.h" -static const uint32_t kCrc32Table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; // kCrc32Table - class CRC32 { private: - uint32_t _crc = 0xFFFFFFFF; - - void AddData(const uint8_t* pData, const std::streamoff length); + static uint32_t crc32_16bytes(const void* data, size_t length, uint32_t previousCrc32); public: static uint32_t GetCRC(uint8_t *buffer, std::streamoff length); diff --git a/Utilities/Utilities.vcxproj b/Utilities/Utilities.vcxproj index 235aa4d9..fa69d116 100644 --- a/Utilities/Utilities.vcxproj +++ b/Utilities/Utilities.vcxproj @@ -441,6 +441,7 @@ + @@ -562,6 +563,7 @@ + diff --git a/Utilities/Utilities.vcxproj.filters b/Utilities/Utilities.vcxproj.filters index 29e0c7c7..38804867 100644 --- a/Utilities/Utilities.vcxproj.filters +++ b/Utilities/Utilities.vcxproj.filters @@ -164,6 +164,9 @@ Header Files + + Header Files + @@ -283,5 +286,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Utilities/WavReader.cpp b/Utilities/WavReader.cpp new file mode 100644 index 00000000..7919bdca --- /dev/null +++ b/Utilities/WavReader.cpp @@ -0,0 +1,124 @@ +#include "stdafx.h" +#include "WavReader.h" + +shared_ptr WavReader::Create(uint8_t* wavData, uint32_t length) +{ + //Basic WAV file read checks (should be using FourCC logic instead, but this will do for now) + if(!wavData || length < 100) { + return nullptr; + } + if(memcmp(wavData, "RIFF", 4) || memcmp(wavData + 8, "WAVE", 4) || memcmp(wavData + 12, "fmt ", 4)) { + return nullptr; + } + + uint32_t channelCount = wavData[22] | (wavData[23] << 8); + if(channelCount != 1) { + //Only mono files are supported at the moment + return nullptr; + } + + uint32_t fmtSize = wavData[16] | (wavData[17] << 8) | (wavData[18] << 16) | (wavData[19] << 24); + if(memcmp(wavData + 20 + fmtSize, "data", 4)) { + //Couldn't find data chunk + return nullptr; + } + + uint32_t bitsPerSample = wavData[34] | (wavData[35] << 8); + if(bitsPerSample != 16) { + //Only support 16-bit samples for now + return nullptr; + } + + uint32_t sampleRate = wavData[24] | (wavData[25] << 8) | (wavData[26] << 16) | (wavData[27] << 24); + + shared_ptr r(new WavReader()); + r->_fileData = wavData; + r->_fileSize = length; + r->_fileSampleRate = sampleRate; + r->_dataStartOffset = 28 + fmtSize; + return r; +} + +WavReader::WavReader() +{ + _done = true; + _prevSample = 0; + _sampleRate = 0; + _blip = blip_new(10000); + _outputBuffer = new int16_t[20000]; +} + +WavReader::~WavReader() +{ + blip_delete(_blip); + delete[] _outputBuffer; +} + +void WavReader::Play(uint32_t startSample) +{ + _prevSample = 0; + _done = false; + _fileOffset = _dataStartOffset + startSample * 2; + + blip_clear(_blip); + blip_set_rates(_blip, _fileSampleRate, _sampleRate); +} + +bool WavReader::IsPlaybackOver() +{ + return _done; +} + +void WavReader::SetSampleRate(uint32_t sampleRate) +{ + _sampleRate = sampleRate; +} + +void WavReader::LoadSamples(uint32_t samplesToLoad) +{ + uint32_t samplesRead = 0; + + for(uint32_t i = _fileOffset; i < _fileSize && samplesRead < samplesToLoad; i+=2) { + int16_t sample = _fileData[i] | (_fileData[i + 1] << 8); + + blip_add_delta(_blip, samplesRead, sample - _prevSample); + + _prevSample = sample; + + _fileOffset += 2; + samplesRead++; + + if(samplesRead < samplesToLoad && i + 2 >= _fileSize) { + _done = true; + break; + } + } + + blip_end_frame(_blip, samplesRead); +} + +void WavReader::ApplySamples(int16_t *buffer, size_t sampleCount, double volume) +{ + if(_done) { + return; + } + + //Volume is set to 10 when volume is set to 100% in the UI + volume /= 10.0; + + LoadSamples((uint32_t)sampleCount * _fileSampleRate / _sampleRate + 1 - blip_samples_avail(_blip)); + + int samplesRead = blip_read_samples(_blip, _outputBuffer, (int)sampleCount, 0); + for(size_t i = 0, len = samplesRead; i < len; i++) { + int16_t sample = (int16_t)((int32_t)_outputBuffer[i] * volume); + + //Apply to both left and right channels + buffer[i*2] += sample; + buffer[i*2+1] += sample; + } +} + +int32_t WavReader::GetPosition() +{ + return _done ? -1 : (_fileOffset - _dataStartOffset) / 2; +} \ No newline at end of file diff --git a/Utilities/WavReader.h b/Utilities/WavReader.h new file mode 100644 index 00000000..110042e6 --- /dev/null +++ b/Utilities/WavReader.h @@ -0,0 +1,39 @@ +#pragma once +#include "stdafx.h" +#include "../Utilities/blip_buf.h" + +class WavReader +{ +private: + int16_t* _outputBuffer; + + uint8_t* _fileData; + uint32_t _fileOffset; + uint32_t _fileSize; + uint32_t _dataStartOffset; + + int16_t _prevSample; + + bool _done; + + blip_t* _blip; + + uint32_t _fileSampleRate; + uint32_t _sampleRate; + + void LoadSamples(uint32_t samplesToLoad); + int16_t ReadSample(); + + WavReader(); + +public: + static shared_ptr Create(uint8_t* wavData, uint32_t length); + + ~WavReader(); + + void Play(uint32_t startSample); + bool IsPlaybackOver(); + void SetSampleRate(uint32_t sampleRate); + void ApplySamples(int16_t* buffer, size_t sampleCount, double volume); + int32_t GetPosition(); +}; diff --git a/Utilities/stdafx.h b/Utilities/stdafx.h index 23f1bef7..c33f81bf 100644 --- a/Utilities/stdafx.h +++ b/Utilities/stdafx.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include