void CCore::_MessageProc(const TWinMessage &stMsg) { switch (stMsg.uiMsgType) { case WMT_REDRAW: _clDelMLoop.Invoke(); break; case WMT_CLOSE: _bDoExit = true; break; case WMT_DESTROY: AddToLog("Finalizing Engine..."); if (!_clDelFree.IsNull()) { AddToLog("Calling user finalization procedure..."); _clDelFree.Invoke(); AddToLog("Done."); } break; default: break; } }
HRESULT CEngine::InitWindowAndSubsystems(const char* WindowTitle, E_ENGINE_INITIALISATION_FLAGS InitFlags) { if (!(InitFlags & EIF_NO_LOGGING)) { _LogFile.open("EngineLog.txt", ios::out | ios::trunc); _LogFile << "KSU Engine Log File" << endl; } _WindowInit((char *)WindowTitle, InitFlags); _OpenGLInit(); //TODO: При реализации наследников, откомментировать. _pInput = new CInput(); _pResourceManager = new CResourceManager(this); _pPhysics = new CPhysics(this); _pRender = new CRender(this); //_pSound = new CSound(); AddToLog("Engine initialized!"); _MainLoop(); if (_LogFile.is_open()) _LogFile.close(); return H_OK; }
void PacketLogger::OnDirectSocketSend(const char *data, const BitSize_t bitsUsed, SystemAddress remoteSystemAddress) { if (logDirectMessages==false) return; char str[256]; FormatLine(str, "Snd", "Raw", 0, 0, data[0], bitsUsed, RakNet::GetTime(), rakPeerInterface->GetExternalID(remoteSystemAddress), remoteSystemAddress, (unsigned int)-1,(unsigned int)-1,(unsigned int)-1,(unsigned int)-1); AddToLog(str); }
HRESULT CALLBACK CCore::InitializeEngine(uint uiResX, uint uiResY, const char* pcApplicationName, E_ENGINE_INIT_FLAGS eInitFlags) { if (!(eInitFlags & EIF_NO_LOGGING)) { _clLogFile.setf(ios_base::right, ios_base::adjustfield); _clLogFile.open("log.txt", ios::out|ios::trunc); TSysTimeAndDate time; GetLocalTimaAndDate(time); _clLogFile << "JTS Engine Log File" << endl; _clLogFile << "Log Started at " << time.ui16Day << "." << time.ui16Month << "." << time.ui16Year << "." << endl; } if (SUCCEEDED(_pMainWindow->InitWindow(&_clDelMLoop, &_clDelMProc))) { _pMainWindow->SetCaption(pcApplicationName); if ( (eInitFlags & EIF_NATIVE_RESOLUTION) && (eInitFlags & EIF_FULL_SCREEN)) GetDisplaySize(uiResX, uiResY); if (FAILED(_pMainWindow->ConfigureWindow(uiResX, uiResY, eInitFlags & EIF_FULL_SCREEN))) return E_ABORT; _pInput = new CInput(this); AddToLog("Engine initialized."); if (!_clDelInit.IsNull()) { AddToLog("Calling user initialization procedure..."); _clDelInit.Invoke(); AddToLog("Done."); } _ui64TimeOld = GetPerfTimer()/1000 - _uiProcessInterval; return _pMainWindow->BeginMainLoop(); } else return E_ABORT; }
void ATSkeletonWindow::disconnectTunnel( Tunnel_c &tunnel ) { Tunnel_c *pt = &tunnel; if ( pt->pProcess == NULL ) return; // not connected? AddToLog( tunnel, "Disconnecting tunnel %s...", qPrintable( pt->strName ) ); qApp->processEvents(); pt->pProcess->kill(); bool bOk = pt->pProcess->waitForFinished( WAIT_FOR_FINISHED_TIMEOUT ); Q_UNUSED( bOk ); delete pt->pProcess; pt->pProcess = NULL; delete pt->pConnector; pt->pConnector = NULL; AddToLog( tunnel, "Disconnected." ); if ( tunnel.twi ) tunnel.twi->setIcon( 0, QPixmap( ":disconnected.png" ) ); int iConnectedCount = 0; for ( TunnelInterator it = m_listTunnels.begin(); it != m_listTunnels.end(); ++it ) if ( it->pProcess ) iConnectedCount++; if ( iConnectedCount == 0 ) emit signalSetTrayIcon( 0 ); if ( pt->iShouldReconnect > 0 ) { AddToLog( tunnel, "Connection lost, reconnecting... (%d)", pt->iShouldReconnect ); pt->iShouldReconnect--; emit signalAutoConnect( &tunnel ); } else { AddToLog( tunnel, "Connection lost, giving up." ); } }
BOOL CInfTlk::Open(const char *pszFilename) { AddToLog("Opening Dialog.tlk:\n"); if (!CFile::Open(pszFilename,CFile::modeRead|CFile::shareDenyNone)) return(FALSE); AddToLog(" Reading dialog header.\n"); if (Read(&m_tlkHeader,sizeof(INF_TLK_HEADER)) != sizeof(INF_TLK_HEADER)) { AfxMessageBox("Unabled to read the header from the .tlk file."); return(FALSE); } AddToLog(" Allocating memory for string entries.\n"); m_pEntries = new STRINGENTRY[m_tlkHeader.dwStringCount]; if (!m_pEntries) { AfxMessageBox("Unable to allocate memory for string index table."); return(FALSE); } AddToLog(" Reading string entries.\n"); INF_TLK_ENTRY entry; for (int i=0;i<(int)m_tlkHeader.dwStringCount;i++) { if (Read(&entry,sizeof(INF_TLK_ENTRY)) != sizeof(INF_TLK_ENTRY)) { AfxMessageBox("Failed reading a talk file entry."); return(FALSE); } m_pEntries[i].dwOffset = entry.dwOffset + m_tlkHeader.dwStringOffset; m_pEntries[i].dwLength = entry.dwLength; m_pEntries[i].wUnknown = entry.wUnknown; } TRACE("TLK String Count : %d\n",m_tlkHeader.dwStringCount); AddToLog(" Done with Dialog.tlk\n"); return(TRUE); }
void ATSkeletonWindow::connected( Tunnel_c &tunnel ) { if ( tunnel.twi != NULL ) { tunnel.twi->setIcon( 0, QPixmap( ":connected.png" ) ); emit signalSetTrayIcon( 1 ); } tunnel.iShouldReconnect = tunnel.bAutoReconnect ? CONNECTION_RETRIES : 0; AddToLog( tunnel, "Connected." ); }
void PacketLogger::OnInternalPacket(InternalPacket *internalPacket, unsigned frameNumber, SystemAddress remoteSystemAddress, RakNetTime time, bool isSend) { char str[256]; const char* sendType = (isSend) ? "Snd" : "Rcv"; SystemAddress localSystemAddress = rakPeer->GetInternalID(); // TODO - put this back in a different form /* if (internalPacket->isAcknowledgement) { if (printAcks) { if (printId==false) sprintf(str, "%s,Ack,%5i,%5i, NIL, 1,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,time, localSystemAddress.binaryAddress, localSystemAddress.port, remoteSystemAddress.binaryAddress, remoteSystemAddress.port); else sprintf(str, "%s,Ack,%i,%i,NIL,1,%i,%u:%i,%u:%i\n",sendType, internalPacket->messageNumber,frameNumber,time, localSystemAddress.binaryAddress, localSystemAddress.port, remoteSystemAddress.binaryAddress, remoteSystemAddress.port); } else str[0]=0; } else */ { if (internalPacket->data[0]==ID_TIMESTAMP && internalPacket->data[sizeof(unsigned char)+sizeof(RakNetTime)]!=ID_RPC) { FormatLine(str, sendType, "Tms", internalPacket->messageNumber, frameNumber, internalPacket->data[1+sizeof(int)], internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); } else if (internalPacket->data[0]==ID_RPC || (internalPacket->dataBitLength>(sizeof(unsigned char)+sizeof(RakNetTime))*8 && internalPacket->data[0]==ID_TIMESTAMP && internalPacket->data[sizeof(unsigned char)+sizeof(RakNetTime)]==ID_RPC)) { const char *uniqueIdentifier = rakPeer->GetRPCString((const char*) internalPacket->data, internalPacket->dataBitLength, isSend==true ? remoteSystemAddress : UNASSIGNED_SYSTEM_ADDRESS); if (internalPacket->data[0]==ID_TIMESTAMP) FormatLine(str, sendType, "RpT", internalPacket->messageNumber, frameNumber, uniqueIdentifier, internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); else FormatLine(str, sendType, "Rpc", internalPacket->messageNumber, frameNumber, uniqueIdentifier, internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); } else { FormatLine(str, sendType, "Nrm", internalPacket->messageNumber, frameNumber, internalPacket->data[0], internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); } } AddToLog(str); }
void PacketLogger::OnAck(unsigned int messageNumber, SystemAddress remoteSystemAddress, RakNetTime time) { char str[256]; char str1[64], str2[62]; SystemAddress localSystemAddress = rakPeerInterface->GetExternalID(remoteSystemAddress); localSystemAddress.ToString(true, str1); remoteSystemAddress.ToString(true, str2); char localtime[128]; GetLocalTime(localtime); sprintf(str, "%s,Rcv,Ack,%i,,,,%"PRINTF_TIME_MODIFIER"u,%s,%s,,,,,," , localtime , messageNumber , (unsigned long long) time , str1 , str2 ); AddToLog(str); }
void PacketLogger::WriteMiscellaneous(const char *type, const char *msg) { char str[1024]; char str1[64]; SystemAddress localSystemAddress = rakPeerInterface->GetInternalID(); localSystemAddress.ToString(true, str1); RakNetTime time = RakNet::GetTime(); char localtime[128]; GetLocalTime(localtime); sprintf(str, "%s,Lcl,%s,,,,,%"PRINTF_TIME_MODIFIER"u,%s,,,,,,,%s" , localtime , type , (unsigned long long) time , str1 , msg ); AddToLog(msg); }
void PacketLogger::OnPushBackPacket(const char *data, const BitSize_t bitsUsed, SystemAddress remoteSystemAddress) { char str[256]; char str1[64], str2[62]; SystemAddress localSystemAddress = rakPeerInterface->GetExternalID(remoteSystemAddress); localSystemAddress.ToString(true, str1); remoteSystemAddress.ToString(true, str2); RakNetTime time = RakNet::GetTime(); char localtime[128]; GetLocalTime(localtime); sprintf(str, "%s,Lcl,PBP,,,%s,%i,%"PRINTF_TIME_MODIFIER"u,%s,%s,,,,,," , localtime , BaseIDTOString(data[0]) , bitsUsed , (unsigned long long) time , str1 , str2 ); AddToLog(str); }
bool CStatusView::Show(bool show /*=true*/) { m_shown = show; if (show) { if (m_hiddenLines.size() == MAX_LINECOUNT) { if (m_pTextCtrl) m_pTextCtrl->Clear(); m_nLineCount = 0; m_lineLengths.clear(); } for (std::list<t_line>::const_iterator iter = m_hiddenLines.begin(); iter != m_hiddenLines.end(); iter++) { AddToLog(iter->messagetype, iter->message, iter->time); } m_hiddenLines.clear(); } return wxWindow::Show(show); }
void PacketLogger::OnInternalPacket(InternalPacket *internalPacket, unsigned frameNumber, SystemAddress remoteSystemAddress, RakNetTime time, int isSend) { char str[256]; const char *sendTypes[] = { "Rcv", "Snd", "Err1", "Err2", "Err3", "Err4", "Err5", "Err6", }; const char *sendType = sendTypes[isSend]; SystemAddress localSystemAddress = rakPeerInterface->GetExternalID(remoteSystemAddress); if (internalPacket->data[0]==ID_TIMESTAMP && internalPacket->data[sizeof(unsigned char)+sizeof(RakNetTime)]!=ID_RPC) { FormatLine(str, sendType, "Tms", internalPacket->reliableMessageNumber, frameNumber, internalPacket->data[1+sizeof(int)], internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); } else if (internalPacket->data[0]==ID_RPC || (internalPacket->dataBitLength>(sizeof(unsigned char)+sizeof(RakNetTime))*8 && internalPacket->data[0]==ID_TIMESTAMP && internalPacket->data[sizeof(unsigned char)+sizeof(RakNetTime)]==ID_RPC)) { const char *uniqueIdentifier = rakPeerInterface->GetRPCString((const char*) internalPacket->data, internalPacket->dataBitLength, isSend==1 ? remoteSystemAddress : UNASSIGNED_SYSTEM_ADDRESS); if (internalPacket->data[0]==ID_TIMESTAMP) FormatLine(str, sendType, "RpT", internalPacket->reliableMessageNumber, frameNumber, uniqueIdentifier, internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); else FormatLine(str, sendType, "Rpc", internalPacket->reliableMessageNumber, frameNumber, uniqueIdentifier, internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); } else { FormatLine(str, sendType, "Nrm", internalPacket->reliableMessageNumber, frameNumber, internalPacket->data[0], internalPacket->dataBitLength, (unsigned long long)time, localSystemAddress, remoteSystemAddress, internalPacket->splitPacketId, internalPacket->splitPacketIndex, internalPacket->splitPacketCount, internalPacket->orderingIndex); } AddToLog(str); }
HRESULT CEngine::GetSubSystem(const E_ENGINE_SUBSYSTEM_TYPE SubSystemType, IEngineSubsystem *&SubSystem) { switch (SubSystemType) { case KSU::ES_INPUT: SubSystem = (IEngineSubsystem *&)_pInput; break; case KSU::ES_PHYSICS: SubSystem = (IEngineSubsystem *&)_pPhysics; break; case KSU::ES_RENDER: SubSystem = (IEngineSubsystem *&)_pRender; break; case KSU::ES_RESOURSE_MANAGER: SubSystem = (IEngineSubsystem *&)_pResourceManager; break; case KSU::ES_SOUND: SubSystem = (IEngineSubsystem *&)_pSound; break; default: AddToLog("No such subsystem!",true); break; } return H_OK; }
void CStatusView::AddToLog(CLogmsgNotification *pNotification) { AddToLog(pNotification->msgType, pNotification->msg, wxDateTime::Now()); }
void ATSkeletonWindow::connectTunnel( Tunnel_c &tunnel ) { Tunnel_c *pt = &tunnel; AddToLog( tunnel, "Connecting tunnel %s...", qPrintable( pt->strName ) ); AddToLog( tunnel, "Host: %s - Tunnel: %d:%s:%d", qPrintable( pt->strSSHHost ), pt->iLocalPort, qPrintable( pt->strRemoteHost ), pt->iRemotePort ); if ( pt->strSSHHost.isEmpty() ) { AddToLog( tunnel, "Error: Tunnel %s has no host, please check the settings.", qPrintable( pt->strName ) ); return; } #ifdef WIN32 QString strPlink = "plink.exe"; // Check that the executable is found { QDir dir( argv0 ); dir.cdUp(); if ( !dir.exists( strPlink ) ) { const char *ptr = argv0, *ptr2 = argv0; while ( *ptr2 ) { if ( *ptr2 == '\\' ) ptr = ptr2+1; ptr2++; } AddToLog( tunnel, "Error: Could not find %s, please check that it is in the same directory as %s.", qPrintable( strPlink ), ptr ); return; } } #else QString strPlink = "ssh"; #endif if ( pt->pProcess != NULL ) return; // already connected? if ( tunnel.twi ) tunnel.twi->setIcon( 0, QPixmap( ":connecting.png" ) ); //QTreeWidgetItem *twi = getTreeItemFromTunnelIndex( iTunnelIndex ); //if ( twi ) twi->setIcon( 0, QPixmap( ":connecting.png" ) ); ATASSERT( pt->pConnector == NULL ); pt->pConnector = new ATTunnelConnector_c( this, &tunnel ); pt->pProcess = new QProcess; pt->pProcess->setProcessChannelMode( QProcess::MergedChannels ); QString strCommand; strCommand += strPlink + " "; strCommand += "-v "; #ifdef _WIN32 QStringList strListSSHHost = pt->strSSHHost.split( ':', QString::SkipEmptyParts ); if ( strListSSHHost.count() == 1 ) strListSSHHost << "22"; strCommand += strListSSHHost.at(0) + " -P " + strListSSHHost.at(1) + " "; #else strCommand += pt->strSSHHost + " "; #endif if ( !pt->strUsername.isEmpty() ) strCommand += QString( "-l %1 " ).arg( pt->strUsername ); if ( pt->bCompression ) strCommand += "-C "; strCommand += ( pt->iSSH1or2 == 1 ) ? "-1 " : "-2 "; if ( pt->iDirection == 0 ) // Local -> Remote { IF_NWIN32( strCommand += "-g " ); strCommand += QString( "-L %1:%2:%3 " ).arg( pt->iLocalPort ).arg( pt->strRemoteHost).arg( pt->iRemotePort ); } else // Remote -> Local { strCommand += QString( "-R %1:%2:%3 " ).arg( pt->iLocalPort ).arg( pt->strRemoteHost).arg( pt->iRemotePort ); } if ( !pt->strSSHKeyFile.isEmpty() ) strCommand += QString( "-i %1 " ).arg( pt->strSSHKeyFile ); strCommand += pt->strExtraArguments; ATVERIFY( connect( pt->pProcess, SIGNAL( readyReadStandardOutput() ), pt->pConnector, SLOT( slotProcessReadStandardOutput() ) ) ); ATVERIFY( connect( pt->pProcess, SIGNAL( readyReadStandardError() ), pt->pConnector, SLOT( slotProcessReadStandardError() ) ) ); ATVERIFY( connect( pt->pProcess, SIGNAL( error(QProcess::ProcessError) ), pt->pConnector, SLOT( slotProcessError(QProcess::ProcessError) ) ) ); ATVERIFY( connect( pt->pProcess, SIGNAL( finished(int, QProcess::ExitStatus) ), pt->pConnector, SLOT( slotProcessFinished(int, QProcess::ExitStatus) ) ) ); ATVERIFY( connect( pt->pConnector, SIGNAL( finished(Tunnel_c*) ), this, SLOT( slotConnectorFinished(Tunnel_c*) ), Qt::QueuedConnection ) ); AddToLog( tunnel, "%s", qPrintable( strCommand ) ); pt->pProcess->start( strCommand ); }
bool CSoundFile::ReadITQ(FileReader &file, ModLoadingFlags loadFlags) //------------------------------------------------------------------ { file.Rewind(); ITFileHeader fileHeader; if(!file.ReadConvertEndianness(fileHeader) || (memcmp(fileHeader.id, "ITQM", 4)) || fileHeader.insnum > 0xFF || fileHeader.smpnum >= MAX_SAMPLES || !file.CanRead(fileHeader.ordnum + (fileHeader.insnum + fileHeader.smpnum + fileHeader.patnum) * 4)) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(); bool interpretModPlugMade = false; // OpenMPT crap at the end of file file.Seek(file.GetLength() - 4); size_t mptStartPos = file.ReadUint32LE(); if(mptStartPos >= file.GetLength() || mptStartPos < 0x100) { mptStartPos = file.GetLength(); } if(!memcmp(fileHeader.id, "tpm.", 4)) { // Legacy MPTM files (old 1.17.02.xx releases) ChangeModTypeTo(MOD_TYPE_MPT); } else { if(mptStartPos <= file.GetLength() - 3 && fileHeader.cwtv > 0x888 && fileHeader.cwtv <= 0xFFF) { file.Seek(mptStartPos); ChangeModTypeTo(file.ReadMagic("228") ? MOD_TYPE_MPT : MOD_TYPE_IT); } else { ChangeModTypeTo(MOD_TYPE_IT); } if(GetType() == MOD_TYPE_IT) { // Which tracker was used to made this? if((fileHeader.cwtv & 0xF000) == 0x5000) { // OpenMPT Version number (Major.Minor) // This will only be interpreted as "made with ModPlug" (i.e. disable compatible playback etc) if the "reserved" field is set to "OMPT" - else, compatibility was used. m_dwLastSavedWithVersion = (fileHeader.cwtv & 0x0FFF) << 16; if(!memcmp(fileHeader.reserved, "OMPT", 4)) interpretModPlugMade = true; } else if(fileHeader.cmwt == 0x888 || fileHeader.cwtv == 0x888) { // OpenMPT 1.17 and 1.18 (raped IT format) // Exact version number will be determined later. interpretModPlugMade = true; } else if(fileHeader.cwtv == 0x0217 && fileHeader.cmwt == 0x0200 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4)) { if(memchr(fileHeader.chnpan, 0xFF, sizeof(fileHeader.chnpan)) != NULL) { // ModPlug Tracker 1.16 (semi-raped IT format) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); madeWithTracker = "ModPlug tracker 1.09 - 1.16"; } else { // OpenMPT 1.17 disguised as this in compatible mode, // but never writes 0xFF in the pan map for unused channels (which is an invalid value). m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); madeWithTracker = "OpenMPT 1.17 (compatibility export)"; } interpretModPlugMade = true; } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0202 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4)) { // ModPlug Tracker b3.3 - 1.09, instruments 557 bytes apart m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 09, 00, 00); madeWithTracker = "ModPlug tracker b3.3 - 1.09"; interpretModPlugMade = true; } } else // case: type == MOD_TYPE_MPT { if (fileHeader.cwtv >= verMptFileVerLoadLimit) { AddToLog(str_LoadingIncompatibleVersion); return false; } else if (fileHeader.cwtv > verMptFileVer) { AddToLog(str_LoadingMoreRecentVersion); } } } if(GetType() == MOD_TYPE_IT) mptStartPos = file.GetLength(); // Read row highlights if((fileHeader.special & ITFileHeader::embedPatternHighlights)) { // MPT 1.09, 1.07 and most likely other old MPT versions leave this blank (0/0), but have the "special" flag set. // Newer versions of MPT and OpenMPT 1.17 *always* write 4/16 here. // Thus, we will just ignore those old versions. if(m_dwLastSavedWithVersion == 0 || m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 03, 02)) { m_nDefaultRowsPerBeat = fileHeader.highlight_minor; m_nDefaultRowsPerMeasure = fileHeader.highlight_major; } #ifdef _DEBUG if((fileHeader.highlight_minor | fileHeader.highlight_major) == 0) { Log("IT Header: Row highlight is 0"); } #endif } m_SongFlags.set(SONG_LINEARSLIDES, (fileHeader.flags & ITFileHeader::linearSlides) != 0); m_SongFlags.set(SONG_ITOLDEFFECTS, (fileHeader.flags & ITFileHeader::itOldEffects) != 0); m_SongFlags.set(SONG_ITCOMPATGXX, (fileHeader.flags & ITFileHeader::itCompatGxx) != 0); m_SongFlags.set(SONG_EMBEDMIDICFG, (fileHeader.flags & ITFileHeader::reqEmbeddedMIDIConfig) || (fileHeader.special & ITFileHeader::embedMIDIConfiguration)); m_SongFlags.set(SONG_EXFILTERRANGE, (fileHeader.flags & ITFileHeader::extendedFilterRange) != 0); mpt::String::Read<mpt::String::spacePadded>(songName, fileHeader.songname); // Global Volume m_nDefaultGlobalVolume = fileHeader.globalvol << 1; if(m_nDefaultGlobalVolume > MAX_GLOBAL_VOLUME) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; if(fileHeader.speed) m_nDefaultSpeed = fileHeader.speed; m_nDefaultTempo = std::max(uint8(32), fileHeader.tempo); // Tempo 31 is possible. due to conflicts with the rest of the engine, let's just clamp it to 32. m_nSamplePreAmp = std::min(fileHeader.mv, uint8(128)); // Reading Channels Pan Positions for(CHANNELINDEX i = 0; i < 64; i++) if(fileHeader.chnpan[i] != 0xFF) { ChnSettings[i].Reset(); ChnSettings[i].nVolume = Clamp(fileHeader.chnvol[i], uint8(0), uint8(64)); if(fileHeader.chnpan[i] & 0x80) ChnSettings[i].dwFlags.set(CHN_MUTE); uint8 n = fileHeader.chnpan[i] & 0x7F; if(n <= 64) ChnSettings[i].nPan = n * 4; if(n == 100) ChnSettings[i].dwFlags.set(CHN_SURROUND); } // Reading orders file.Seek(sizeof(ITFileHeader)); if(GetType() == MOD_TYPE_IT) { Order.ReadAsByte(file, fileHeader.ordnum); } else { if(fileHeader.cwtv > 0x88A && fileHeader.cwtv <= 0x88D) { Order.Deserialize(file); } else { Order.ReadAsByte(file, fileHeader.ordnum); // Replacing 0xFF and 0xFE with new corresponding indexes Order.Replace(0xFE, Order.GetIgnoreIndex()); Order.Replace(0xFF, Order.GetInvalidPatIndex()); } } // Reading instrument, sample and pattern offsets std::vector<uint32> insPos, smpPos, patPos; file.ReadVectorLE(insPos, fileHeader.insnum); file.ReadVectorLE(smpPos, fileHeader.smpnum); file.ReadVectorLE(patPos, fileHeader.patnum); // Find the first parapointer. // This is used for finding out whether the edit history is actually stored in the file or not, // as some early versions of Schism Tracker set the history flag, but didn't save anything. // We will consider the history invalid if it ends after the first parapointer. uint32 minPtr = Util::MaxValueOfType(minPtr); for(uint16 n = 0; n < fileHeader.insnum; n++) { if(insPos[n] > 0) { minPtr = std::min(minPtr, insPos[n]); } } for(uint16 n = 0; n < fileHeader.smpnum; n++) { if(smpPos[n] > 0) { minPtr = std::min(minPtr, smpPos[n]); } } for(uint16 n = 0; n < fileHeader.patnum; n++) { if(patPos[n] > 0) { minPtr = std::min(minPtr, patPos[n]); } } if(fileHeader.special & ITFileHeader::embedSongMessage) { minPtr = std::min(minPtr, fileHeader.msgoffset); } // Reading IT Edit History Info // This is only supposed to be present if bit 1 of the special flags is set. // However, old versions of Schism and probably other trackers always set this bit // even if they don't write the edit history count. So we have to filter this out... // This is done by looking at the parapointers. If the history data end after // the first parapointer, we assume that it's actually no history data. if(fileHeader.special & ITFileHeader::embedEditHistory) { const uint16 nflt = file.ReadUint16LE(); if(file.CanRead(nflt * sizeof(ITHistoryStruct)) && file.GetPosition() + nflt * sizeof(ITHistoryStruct) <= minPtr) { m_FileHistory.reserve(nflt); for(size_t n = 0; n < nflt; n++) { FileHistory mptHistory; ITHistoryStruct itHistory; file.ReadConvertEndianness(itHistory); itHistory.ConvertToMPT(mptHistory); m_FileHistory.push_back(mptHistory); } } else { // Oops, we were not supposed to read this. file.SkipBack(2); } } else if(fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0 && fileHeader.cmwt == 0x0214 && fileHeader.cwtv == 0x0214 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4) && (fileHeader.special & (ITFileHeader::embedEditHistory | ITFileHeader::embedPatternHighlights)) == 0) { // Another non-conforming application is unmo3 < v2.4.0.1, which doesn't set the special bit // at all, but still writes the two edit history length bytes (zeroes)... if(file.ReadUint16LE() != 0) { // These were not zero bytes -> We're in the wrong place! file.SkipBack(2); madeWithTracker = "UNMO3"; } } // Reading MIDI Output & Macros if(m_SongFlags[SONG_EMBEDMIDICFG] && file.Read(m_MidiCfg)) { m_MidiCfg.Sanitize(); } // Ignore MIDI data. Fixes some files like denonde.it that were made with old versions of Impulse Tracker (which didn't support Zxx filters) and have Zxx effects in the patterns. if(fileHeader.cwtv < 0x0214) { MemsetZero(m_MidiCfg.szMidiSFXExt); MemsetZero(m_MidiCfg.szMidiZXXExt); m_SongFlags.set(SONG_EMBEDMIDICFG); } if(file.ReadMagic("MODU")) { madeWithTracker = "BeRoTracker"; } // Read pattern names: "PNAM" FileReader patNames; if(file.ReadMagic("PNAM")) { patNames = file.GetChunk(file.ReadUint32LE()); } m_nChannels = GetModSpecifications().channelsMin; // Read channel names: "CNAM" if(file.ReadMagic("CNAM")) { FileReader chnNames = file.GetChunk(file.ReadUint32LE()); const CHANNELINDEX readChns = std::min(MAX_BASECHANNELS, static_cast<CHANNELINDEX>(chnNames.GetLength() / MAX_CHANNELNAME)); m_nChannels = readChns; for(CHANNELINDEX i = 0; i < readChns; i++) { chnNames.ReadString<mpt::String::maybeNullTerminated>(ChnSettings[i].szName, MAX_CHANNELNAME); } } // Read mix plugins information if(file.CanRead(9)) { LoadMixPlugins(file); } // Read Song Message if(fileHeader.special & ITFileHeader::embedSongMessage) { if(fileHeader.msglength > 0 && file.Seek(fileHeader.msgoffset)) { // Generally, IT files should use CR for line endings. However, ChibiTracker uses LF. One could do... // if(itHeader.cwtv == 0x0214 && itHeader.cmwt == 0x0214 && itHeader.reserved == ITFileHeader::chibiMagic) --> Chibi detected. // But we'll just use autodetection here: songMessage.Read(file, fileHeader.msglength, SongMessage::leAutodetect); } } // Reading Instruments m_nInstruments = 0; if(fileHeader.flags & ITFileHeader::instrumentMode) { m_nInstruments = std::min(fileHeader.insnum, INSTRUMENTINDEX(MAX_INSTRUMENTS - 1)); } for(INSTRUMENTINDEX i = 0; i < GetNumInstruments(); i++) { if(insPos[i] > 0 && file.Seek(insPos[i]) && file.CanRead(fileHeader.cmwt < 0x200 ? sizeof(ITOldInstrument) : sizeof(ITInstrument))) { ModInstrument *instrument = AllocateInstrument(i + 1); if(instrument != nullptr) { ITInstrToMPT(file, *instrument, fileHeader.cmwt); // MIDI Pitch Wheel Depth is a global setting in IT. Apply it to all instruments. instrument->midiPWD = fileHeader.pwd; } } } // In order to properly compute the position, in file, of eventual extended settings // such as "attack" we need to keep the "real" size of the last sample as those extra // setting will follow this sample in the file FileReader::off_t lastSampleOffset = 0; if(fileHeader.smpnum > 0) { lastSampleOffset = smpPos[fileHeader.smpnum - 1] + sizeof(ITSample); } //// #ITQ // Reading Samples m_nSamples = std::min(fileHeader.smpnum, SAMPLEINDEX(MAX_SAMPLES - 1)); size_t nbytes = 0; // size of sample data in file for(SAMPLEINDEX i = 0; i < GetNumSamples(); i++) { ITQSample sampleHeader; if(smpPos[i] > 0 && file.Seek(smpPos[i]) && file.ReadConvertEndianness(sampleHeader)) { if(!memcmp(sampleHeader.id, "ITQS", 4)) { size_t sampleOffset = sampleHeader.ConvertToMPT(Samples[i + 1]); mpt::String::Read<mpt::String::spacePadded>(m_szNames[i + 1], sampleHeader.name); if((loadFlags & loadSampleData) && file.Seek(sampleOffset)) { Samples[i+1].originalSize = sampleHeader.nbytes; sampleHeader.GetSampleFormatITQ(fileHeader.cwtv).ReadSample(Samples[i + 1], file); lastSampleOffset = std::max(lastSampleOffset, file.GetPosition()); } } } } m_nSamples = std::max(SAMPLEINDEX(1), GetNumSamples()); m_nMinPeriod = 8; m_nMaxPeriod = 0xF000; PATTERNINDEX numPats = std::min(static_cast<PATTERNINDEX>(patPos.size()), GetModSpecifications().patternsMax); if(numPats != patPos.size()) { // Hack: Notify user here if file contains more patterns than what can be read. AddToLog(mpt::String::Print(str_PatternSetTruncationNote, patPos.size(), numPats)); } if(!(loadFlags & loadPatternData)) { numPats = 0; } // Checking for number of used channels, which is not explicitely specified in the file. for(PATTERNINDEX pat = 0; pat < numPats; pat++) { if(patPos[pat] == 0 || !file.Seek(patPos[pat])) continue; uint16 len = file.ReadUint16LE(); ROWINDEX numRows = file.ReadUint16LE(); if(numRows < GetModSpecifications().patternRowsMin || numRows > GetModSpecifications().patternRowsMax || !file.Skip(4)) continue; FileReader patternData = file.GetChunk(len); ROWINDEX row = 0; std::vector<uint8> chnMask(GetNumChannels()); while(row < numRows && patternData.AreBytesLeft()) { uint8 b = patternData.ReadUint8(); if(!b) { row++; continue; } CHANNELINDEX ch = (b & IT_bitmask_patternChanField_c); // 0x7f We have some data grab a byte keeping only 7 bits if(ch) { ch = (ch - 1);// & IT_bitmask_patternChanMask_c; // 0x3f mask of the byte again, keeping only 6 bits } if(ch >= chnMask.size()) { chnMask.resize(ch + 1, 0); } if(b & IT_bitmask_patternChanEnabled_c) // 0x80 check if the upper bit is enabled. { chnMask[ch] = patternData.ReadUint8(); // set the channel mask for this channel. } // Channel used if(chnMask[ch] & 0x0F) // if this channel is used set m_nChannels { if(ch >= GetNumChannels() && ch < MAX_BASECHANNELS) { m_nChannels = ch + 1; } } // Now we actually update the pattern-row entry the note,instrument etc. // Note if(chnMask[ch] & 1) patternData.Skip(1); // Instrument if(chnMask[ch] & 2) patternData.Skip(1); // Volume if(chnMask[ch] & 4) patternData.Skip(1); // Effect if(chnMask[ch] & 8) patternData.Skip(2); } } // Compute extra instruments settings position if(lastSampleOffset > 0) { file.Seek(lastSampleOffset); } // Load instrument and song extensions. LoadExtendedInstrumentProperties(file, &interpretModPlugMade); if(interpretModPlugMade) { m_nMixLevels = mixLevels_original; } // We need to do this here, because if there no samples (so lastSampleOffset = 0), we need to look after the last pattern (sample data normally follows pattern data). // And we need to do this before reading the patterns because m_nChannels might be modified by LoadExtendedSongProperties. *sigh* LoadExtendedSongProperties(GetType(), file, &interpretModPlugMade); m_nTempoMode = tempo_mode_modern; // Reading Patterns Patterns.ResizeArray(std::max(MAX_PATTERNS, numPats)); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { if(patPos[pat] == 0 || !file.Seek(patPos[pat])) { // Empty 64-row pattern if(Patterns.Insert(pat, 64)) { AddToLog(mpt::String::Print("Allocating patterns failed starting from pattern %1", pat)); break; } // Now (after the Insert() call), we can read the pattern name. CopyPatternName(Patterns[pat], patNames); continue; } uint16 len = file.ReadUint16LE(); ROWINDEX numRows = file.ReadUint16LE(); if(numRows < GetModSpecifications().patternRowsMin || numRows > GetModSpecifications().patternRowsMax || !file.Skip(4) || Patterns.Insert(pat, numRows)) continue; FileReader patternData = file.GetChunk(len); // Now (after the Insert() call), we can read the pattern name. CopyPatternName(Patterns[pat], patNames); std::vector<uint8> chnMask(GetNumChannels()); std::vector<ModCommand> lastValue(GetNumChannels(), ModCommand::Empty()); ModCommand *m = Patterns[pat]; ROWINDEX row = 0; while(row < numRows && patternData.AreBytesLeft()) { uint8 b = patternData.ReadUint8(); if(!b) { row++; m += GetNumChannels(); continue; } CHANNELINDEX ch = b & IT_bitmask_patternChanField_c; // 0x7f if(ch) { ch = (ch - 1); //& IT_bitmask_patternChanMask_c; // 0x3f } if(ch >= chnMask.size()) { chnMask.resize(ch + 1, 0); lastValue.resize(ch + 1, ModCommand::Empty()); ASSERT(chnMask.size() <= GetNumChannels()); } if(b & IT_bitmask_patternChanEnabled_c) // 0x80 { chnMask[ch] = patternData.ReadUint8(); } // Now we grab the data for this particular row/channel. if((chnMask[ch] & 0x10) && (ch < m_nChannels)) { m[ch].note = lastValue[ch].note; } if((chnMask[ch] & 0x20) && (ch < m_nChannels)) { m[ch].instr = lastValue[ch].instr; } if((chnMask[ch] & 0x40) && (ch < m_nChannels)) { m[ch].volcmd = lastValue[ch].volcmd; m[ch].vol = lastValue[ch].vol; } if((chnMask[ch] & 0x80) && (ch < m_nChannels)) { m[ch].command = lastValue[ch].command; m[ch].param = lastValue[ch].param; } if(chnMask[ch] & 1) // Note { uint8 note = patternData.ReadUint8(); if(ch < m_nChannels) { if(note < 0x80) note++; if(!(GetType() & MOD_TYPE_MPT)) { if(note > NOTE_MAX && note < 0xFD) note = NOTE_FADE; else if(note == 0xFD) note = NOTE_NONE; } m[ch].note = note; lastValue[ch].note = note; } } if(chnMask[ch] & 2) { uint8 instr = patternData.ReadUint8(); if(ch < m_nChannels) { m[ch].instr = instr; lastValue[ch].instr = instr; } } if(chnMask[ch] & 4) { uint8 vol = patternData.ReadUint8(); if(ch < m_nChannels) { // 0-64: Set Volume if(vol <= 64) { m[ch].volcmd = VOLCMD_VOLUME; m[ch].vol = vol; } else // 128-192: Set Panning if(vol >= 128 && vol <= 192) { m[ch].volcmd = VOLCMD_PANNING; m[ch].vol = vol - 128; } else // 65-74: Fine Volume Up if(vol < 75) { m[ch].volcmd = VOLCMD_FINEVOLUP; m[ch].vol = vol - 65; } else // 75-84: Fine Volume Down if(vol < 85) { m[ch].volcmd = VOLCMD_FINEVOLDOWN; m[ch].vol = vol - 75; } else // 85-94: Volume Slide Up if(vol < 95) { m[ch].volcmd = VOLCMD_VOLSLIDEUP; m[ch].vol = vol - 85; } else // 95-104: Volume Slide Down if(vol < 105) { m[ch].volcmd = VOLCMD_VOLSLIDEDOWN; m[ch].vol = vol - 95; } else // 105-114: Pitch Slide Up if(vol < 115) { m[ch].volcmd = VOLCMD_PORTADOWN; m[ch].vol = vol - 105; } else // 115-124: Pitch Slide Down if(vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else // 193-202: Portamento To if(vol >= 193 && vol <= 202) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else // 203-212: Vibrato depth if(vol >= 203 && vol <= 212) { m[ch].volcmd = VOLCMD_VIBRATODEPTH; m[ch].vol = vol - 203; // Old versions of ModPlug saved this as vibrato speed instead, so let's fix that. if(m[ch].vol && m_dwLastSavedWithVersion && m_dwLastSavedWithVersion <= MAKE_VERSION_NUMERIC(1, 17, 02, 54)) m[ch].volcmd = VOLCMD_VIBRATOSPEED; } else // 213-222: Unused (was velocity) // 223-232: Offset if(vol >= 223 && vol <= 232) { m[ch].volcmd = VOLCMD_OFFSET; m[ch].vol = vol - 223; } lastValue[ch].volcmd = m[ch].volcmd; lastValue[ch].vol = m[ch].vol; } } // Reading command/param if(chnMask[ch] & 8) { uint8 cmd = patternData.ReadUint8(); uint8 param = patternData.ReadUint8(); if(ch < m_nChannels) { if(cmd) { m[ch].command = cmd; m[ch].param = param; S3MConvert(m[ch], true); lastValue[ch].command = m[ch].command; lastValue[ch].param = m[ch].param; } } } } } UpgradeModFlags(); if(!m_dwLastSavedWithVersion && fileHeader.cwtv == 0x0888) { // There are some files with OpenMPT extensions, but the "last saved with" field contains 0. // Was there an OpenMPT version that wrote 0 there, or are they hacked? m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); } if(m_dwLastSavedWithVersion && madeWithTracker.empty()) { madeWithTracker = "OpenMPT " + MptVersion::ToStr(m_dwLastSavedWithVersion); if(memcmp(fileHeader.reserved, "OMPT", 4) && (fileHeader.cwtv & 0xF000) == 0x5000) { madeWithTracker += " (compatibility export)"; } else if(MptVersion::IsTestBuild(m_dwLastSavedWithVersion)) { madeWithTracker += " (test build)"; } } else { switch(fileHeader.cwtv >> 12) { case 0: if(!madeWithTracker.empty()) { // BeRoTracker has been detected above. } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0200 && fileHeader.flags == 9 && fileHeader.special == 0 && fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0 && fileHeader.insnum == 0 && fileHeader.patnum + 1 == fileHeader.ordnum && fileHeader.globalvol == 128 && fileHeader.mv == 100 && fileHeader.speed == 1 && fileHeader.sep == 128 && fileHeader.pwd == 0 && fileHeader.msglength == 0 && fileHeader.msgoffset == 0 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4)) { madeWithTracker = "OpenSPC conversion"; } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0200 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4)) { // ModPlug Tracker 1.00a5, instruments 560 bytes apart m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, A5); madeWithTracker = "ModPlug tracker 1.00a5"; interpretModPlugMade = true; } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !memcmp(fileHeader.reserved, "CHBI", 4)) { madeWithTracker = "ChibiTracker"; } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !(fileHeader.special & 3) && !memcmp(fileHeader.reserved, "\0\0\0\0", 4) && !strcmp(Samples[1].filename, "XXXXXXXX.YYY")) { madeWithTracker = "CheeseTracker"; } else { if(fileHeader.cmwt > 0x0214) { madeWithTracker = "Impulse Tracker 2.15"; } else if(fileHeader.cwtv > 0x0214) { // Patched update of IT 2.14 (0x0215 - 0x0217 == p1 - p3) // p4 (as found on modland) adds the ITVSOUND driver, but doesn't seem to change // anything as far as file saving is concerned. madeWithTracker = mpt::String::Print("Impulse Tracker 2.14p%1", fileHeader.cwtv - 0x0214); } else { madeWithTracker = mpt::String::Print("Impulse Tracker %1.%2", (fileHeader.cwtv & 0x0F00) >> 8, mpt::fmt::hex0<2>((fileHeader.cwtv & 0xFF))); } } break; case 1: madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv); break; case 6: madeWithTracker = "BeRoTracker"; break; case 7: madeWithTracker = mpt::String::Print("ITMCK %1.%2.%3", (fileHeader.cwtv >> 8) & 0x0F, (fileHeader.cwtv >> 4) & 0x0F, fileHeader.cwtv & 0x0F); break; } } if(GetType() == MOD_TYPE_IT) { // Set appropriate mod flags if the file was not made with MPT. if(!interpretModPlugMade) { SetModFlag(MSF_MIDICC_BUGEMULATION, false); SetModFlag(MSF_OLDVOLSWING, false); SetModFlag(MSF_COMPATIBLE_PLAY, true); } } else { //START - mpt specific: //Using member cwtv on pifh as the version number. const uint16 version = fileHeader.cwtv; if(version > 0x889 && file.Seek(mptStartPos)) { std::istringstream iStrm(std::string(file.GetRawData(), file.BytesLeft())); if(version >= 0x88D) { srlztn::SsbRead ssb(iStrm); ssb.BeginRead("mptm", MptVersion::num); ssb.ReadItem(GetTuneSpecificTunings(), "0", 1, &ReadTuningCollection); ssb.ReadItem(*this, "1", 1, &ReadTuningMap); ssb.ReadItem(Order, "2", 1, &ReadModSequenceOld); ssb.ReadItem(Patterns, FileIdPatterns, strlen(FileIdPatterns), &ReadModPatterns); ssb.ReadItem(Order, FileIdSequences, strlen(FileIdSequences), &ReadModSequences); if(ssb.m_Status & srlztn::SNT_FAILURE) { AddToLog("Unknown error occured while deserializing file."); } } else //Loading for older files. { if(GetTuneSpecificTunings().Deserialize(iStrm)) { AddToLog("Error occured - loading failed while trying to load tune specific tunings."); } else { ReadTuningMap(iStrm, *this); } } } //version condition(MPT) } return true; }
OPENMPT_NAMESPACE_BEGIN // Version changelog: // v1.03: - Relative unicode instrument paths instead of absolute ANSI paths // - Per-path variable string length // - Embedded samples are IT-compressed // (rev. 3249) // v1.02: Explicitely updated format to use new instrument flags representation (rev. 483) // v1.01: Added option to embed instrument headers bool CSoundFile::ReadITProject(FileReader &file, ModLoadingFlags loadFlags) //------------------------------------------------------------------------- { #ifndef MPT_EXTERNAL_SAMPLES // Doesn't really make sense to support this format when there's no support for external files... MPT_UNREFERENCED_PARAMETER(file); MPT_UNREFERENCED_PARAMETER(loadFlags); return false; #else // MPT_EXTERNAL_SAMPLES enum ITPSongFlags { ITP_EMBEDMIDICFG = 0x00001, // Embed macros in file ITP_ITOLDEFFECTS = 0x00004, // Old Impulse Tracker effect implementations ITP_ITCOMPATGXX = 0x00008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) ITP_LINEARSLIDES = 0x00010, // Linear slides vs. Amiga slides ITP_EXFILTERRANGE = 0x08000, // Cutoff Filter has double frequency range (up to ~10Khz) ITP_ITPROJECT = 0x20000, // Is a project file ITP_ITPEMBEDIH = 0x40000, // Embed instrument headers in project file }; uint32 version; FileReader::off_t size; file.Rewind(); // Check file ID if(!file.CanRead(12 + 4 + 24 + 4) || file.ReadUint32LE() != MAGIC4BE('.','i','t','p') // Magic bytes || (version = file.ReadUint32LE()) > 0x00000103 // Format version || version < 0x00000100) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } InitializeGlobals(MOD_TYPE_IT); m_playBehaviour.reset(); file.ReadString<mpt::String::maybeNullTerminated>(m_songName, file.ReadUint32LE()); // Song comments m_songMessage.Read(file, file.ReadUint32LE(), SongMessage::leCR); // Song global config const uint32 songFlags = file.ReadUint32LE(); if(!(songFlags & ITP_ITPROJECT)) { return false; } if(songFlags & ITP_EMBEDMIDICFG) m_SongFlags.set(SONG_EMBEDMIDICFG); if(songFlags & ITP_ITOLDEFFECTS) m_SongFlags.set(SONG_ITOLDEFFECTS); if(songFlags & ITP_ITCOMPATGXX) m_SongFlags.set(SONG_ITCOMPATGXX); if(songFlags & ITP_LINEARSLIDES) m_SongFlags.set(SONG_LINEARSLIDES); if(songFlags & ITP_EXFILTERRANGE) m_SongFlags.set(SONG_EXFILTERRANGE); m_nDefaultGlobalVolume = file.ReadUint32LE(); m_nSamplePreAmp = file.ReadUint32LE(); m_nDefaultSpeed = std::max(uint32(1), file.ReadUint32LE()); m_nDefaultTempo.Set(std::max(uint32(32), file.ReadUint32LE())); m_nChannels = static_cast<CHANNELINDEX>(file.ReadUint32LE()); if(m_nChannels == 0 || m_nChannels > MAX_BASECHANNELS) { return false; } // channel name string length (=MAX_CHANNELNAME) size = file.ReadUint32LE(); // Channels' data for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) { ChnSettings[chn].nPan = std::min(static_cast<uint16>(file.ReadUint32LE()), uint16(256)); ChnSettings[chn].dwFlags.reset(); uint32 flags = file.ReadUint32LE(); if(flags & 0x100) ChnSettings[chn].dwFlags.set(CHN_MUTE); if(flags & 0x800) ChnSettings[chn].dwFlags.set(CHN_SURROUND); ChnSettings[chn].nVolume = std::min(static_cast<uint16>(file.ReadUint32LE()), uint16(64)); file.ReadString<mpt::String::maybeNullTerminated>(ChnSettings[chn].szName, size); } // Song mix plugins { FileReader plugChunk = file.ReadChunk(file.ReadUint32LE()); LoadMixPlugins(plugChunk); } // MIDI Macro config file.ReadStructPartial(m_MidiCfg, file.ReadUint32LE()); m_MidiCfg.Sanitize(); // Song Instruments m_nInstruments = static_cast<INSTRUMENTINDEX>(file.ReadUint32LE()); if(m_nInstruments >= MAX_INSTRUMENTS) { return false; } // Instruments' paths if(version <= 0x00000102) { size = file.ReadUint32LE(); // path string length } std::vector<mpt::PathString> instrPaths(GetNumInstruments()); for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { if(version > 0x00000102) { size = file.ReadUint32LE(); // path string length } std::string path; file.ReadString<mpt::String::maybeNullTerminated>(path, size); if(version <= 0x00000102) { instrPaths[ins] = mpt::PathString::FromLocaleSilent(path); } else { instrPaths[ins] = mpt::PathString::FromUTF8(path); } } // Song Orders size = file.ReadUint32LE(); Order.ReadAsByte(file, size, size, 0xFF, 0xFE); // Song Patterns const PATTERNINDEX numPats = static_cast<PATTERNINDEX>(file.ReadUint32LE()); const PATTERNINDEX numNamedPats = static_cast<PATTERNINDEX>(file.ReadUint32LE()); size_t patNameLen = file.ReadUint32LE(); // Size of each pattern name FileReader pattNames = file.ReadChunk(numNamedPats * patNameLen); // modcommand data length size = file.ReadUint32LE(); if(size != 6) { return false; } for(PATTERNINDEX pat = 0; pat < numPats; pat++) { const ROWINDEX numRows = file.ReadUint32LE(); FileReader patternChunk = file.ReadChunk(numRows * size * GetNumChannels()); // Allocate pattern if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, numRows)) { pattNames.Skip(patNameLen); continue; } if(pat < numNamedPats) { char patName[32]; pattNames.ReadString<mpt::String::maybeNullTerminated>(patName, patNameLen); Patterns[pat].SetName(patName); } // Pattern data size_t numCommands = GetNumChannels() * numRows; if(patternChunk.CanRead(sizeof(MODCOMMAND_ORIGINAL) * numCommands)) { ModCommand *target = Patterns[pat].GetpModCommand(0, 0); while(numCommands-- != 0) { STATIC_ASSERT(sizeof(MODCOMMAND_ORIGINAL) == 6); MODCOMMAND_ORIGINAL data; patternChunk.ReadStruct(data); if(data.command >= MAX_EFFECTS) data.command = CMD_NONE; if(data.volcmd >= MAX_VOLCMDS) data.volcmd = VOLCMD_NONE; if(data.note > NOTE_MAX && data.note < NOTE_MIN_SPECIAL) data.note = NOTE_NONE; *(target++) = data; } } } // Load embedded samples // Read original number of samples m_nSamples = static_cast<SAMPLEINDEX>(file.ReadUint32LE()); LimitMax(m_nSamples, SAMPLEINDEX(MAX_SAMPLES - 1)); // Read number of embedded samples uint32 embeddedSamples = file.ReadUint32LE(); // Read samples for(uint32 smp = 0; smp < embeddedSamples; smp++) { SAMPLEINDEX realSample = static_cast<SAMPLEINDEX>(file.ReadUint32LE()); ITSample sampleHeader; file.ReadConvertEndianness(sampleHeader); FileReader sampleData = file.ReadChunk(file.ReadUint32LE()); if(realSample >= 1 && realSample <= GetNumSamples() && !memcmp(sampleHeader.id, "IMPS", 4) && (loadFlags & loadSampleData)) { sampleHeader.ConvertToMPT(Samples[realSample]); mpt::String::Read<mpt::String::nullTerminated>(m_szNames[realSample], sampleHeader.name); // Read sample data sampleHeader.GetSampleFormat().ReadSample(Samples[realSample], sampleData); } } // Load instruments for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { if(instrPaths[ins].empty()) continue; if(!file.GetFileName().empty()) { instrPaths[ins] = instrPaths[ins].RelativePathToAbsolute(file.GetFileName().GetPath()); } #ifdef MODPLUG_TRACKER else if(GetpModDoc() != nullptr) { instrPaths[ins] = instrPaths[ins].RelativePathToAbsolute(GetpModDoc()->GetPathNameMpt().GetPath()); } #endif // MODPLUG_TRACKER InputFile f(instrPaths[ins]); FileReader file = GetFileReader(f); if(!ReadInstrumentFromFile(ins + 1, file, true)) { AddToLog(LogWarning, MPT_USTRING("Unable to open instrument: ") + instrPaths[ins].ToUnicode()); } } // Extra info data uint32 code = file.ReadUint32LE(); // Embed instruments' header [v1.01] if(version >= 0x00000101 && (songFlags & ITP_ITPEMBEDIH) && code == MAGIC4BE('E', 'B', 'I', 'H')) { code = file.ReadUint32LE(); INSTRUMENTINDEX ins = 1; while(ins <= GetNumInstruments() && file.CanRead(4)) { if(code == MAGIC4BE('M', 'P', 'T', 'S')) { break; } else if(code == MAGIC4BE('S', 'E', 'P', '@') || code == MAGIC4BE('M', 'P', 'T', 'X')) { // jump code - switch to next instrument ins++; } else { ReadExtendedInstrumentProperty(Instruments[ins], code, file); } code = file.ReadUint32LE(); } } // Song extensions if(code == MAGIC4BE('M', 'P', 'T', 'S')) { file.SkipBack(4); LoadExtendedSongProperties(file); } m_nMaxPeriod = 0xF000; m_nMinPeriod = 8; // Before OpenMPT 1.20.01.09, the MIDI macros were always read from the file, even if the "embed" flag was not set. if(m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1,20,01,09) && !m_SongFlags[SONG_EMBEDMIDICFG]) { m_MidiCfg.Reset(); } else if(!m_MidiCfg.IsMacroDefaultSetupUsed()) { m_SongFlags.set(SONG_EMBEDMIDICFG); } m_madeWithTracker = "OpenMPT " + MptVersion::ToStr(m_dwLastSavedWithVersion); return true; #endif // MPT_EXTERNAL_SAMPLES }
void PacketLogger::OnDirectSocketReceive(const char *data, const BitSize_t bitsUsed, SystemAddress remoteSystemAddress) { char str[256]; FormatLine(str, "Rcv", "Raw", 0, 0, data[0], bitsUsed, RakNet::GetTime(), rakPeer->GetInternalID(), remoteSystemAddress,(unsigned int)-1,(unsigned int)-1,(unsigned int)-1,(unsigned int)-1); AddToLog(str); }
void PacketLogger::OnReliabilityLayerPacketError(const char *errorMessage, const BitSize_t bitsUsed, SystemAddress remoteSystemAddress) { char str[1024]; FormatLine(str, "RcvErr", errorMessage, 0, 0, "", bitsUsed, RakNet::GetTime(), rakPeerInterface->GetExternalID(remoteSystemAddress), remoteSystemAddress,(unsigned int)-1,(unsigned int)-1,(unsigned int)-1,(unsigned int)-1); AddToLog(str); }
void PacketLogger::LogHeader(void) { // Last 5 are splitpacket id, split packet index, split packet count, ordering index, suffix AddToLog("Clock,S|R,Typ,Pckt#,Frm #,PktID,BitLn,Time ,Local IP:Port ,RemoteIP:Port,SPID,SPIN,SPCO,OI,Suffix,Miscellaneous\n"); }
BOOL CPalImageList::CreateFromBitmap(HBITMAP hBitmap) { AddToLog("Creating Image List from bitmap.\n"); BITMAP bm; AddToLog(" Getting bitmap info.\n"); if (!::GetObject(hBitmap,sizeof(bm),&bm)) return(FALSE); AddToLog(" Getting DC.\n"); CDC *pDC = AfxGetMainWnd()->GetDC(); if (!pDC) return(FALSE); AddToLog(" Creating compatible bitmap.\n"); CBitmap bmp; if (!bmp.CreateCompatibleBitmap(pDC,bm.bmWidth*2*bm.bmHeight,bm.bmWidth*2)) { AfxGetMainWnd()->ReleaseDC(pDC); return(FALSE); } AddToLog(" Creating compatible DC.\n"); CDC dc; if (!dc.CreateCompatibleDC(pDC)) { AfxGetMainWnd()->ReleaseDC(pDC); return(FALSE); } AddToLog(" Allocating bit buffer.\n"); BYTE *pBits = new BYTE[bm.bmWidth*4*bm.bmHeight]; if (!pBits) { AfxGetMainWnd()->ReleaseDC(pDC); return(FALSE); } BITMAPINFO bmi; memset(&bmi,0,sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biHeight = bm.bmHeight*-1; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biWidth = bm.bmWidth; bmi.bmiHeader.biCompression = BI_RGB; AddToLog(" Getting bitmap bits.\n"); if (!::GetDIBits( pDC->GetSafeHdc(), hBitmap, 0, bm.bmHeight, pBits, &bmi, DIB_RGB_COLORS)) { AfxGetMainWnd()->ReleaseDC(pDC); delete [] pBits; return(FALSE); } CBitmap *pOldBitmap = dc.SelectObject(&bmp); AddToLog(" Creating color samples.\n"); BYTE *ptr; COLORREF clrFixed; RGBQUAD *pQuad; CRect r; int j; for (int i=0;i<bm.bmHeight;i++) { r.top = 0; r.bottom = bm.bmWidth*2; r.left = i * (bm.bmWidth*2); r.right = r.left + bm.bmWidth*2; ptr = pBits + (i * (bm.bmWidth*4)) + 4; // I didn't do the full row. The pointy shape you end up with if you do // all the colors down to a 2x2 square doesn't look as good. The colors // on the right side are the darker versions generally so the color shows // up a little better this way too -- brighter overall. for (j=bm.bmWidth-3;j>=1;j--) { ptr = pBits + (i * (bm.bmWidth*4)) + j*4; pQuad = (RGBQUAD*)ptr; clrFixed = RGB(pQuad->rgbRed,pQuad->rgbGreen,pQuad->rgbBlue); dc.FillSolidRect(&r,clrFixed); r.DeflateRect(1,1); } } dc.SelectObject(pOldBitmap); delete [] pBits; Create(bm.bmWidth*2,bm.bmWidth*2,ILC_COLOR24,0,1); Add(&bmp,RGB(255,255,255)); AddToLog(" Finished creating Image List.\n"); return(TRUE); }
VOID ProcessPacket(SYSTEMTIME rTime, unsigned char *szBuffer, int size, BOOL bFilter) { struct ethernet_802_3 *eth; struct iphdr *ip; struct arppkt *arp; int size_iphdr, size_framehdr, index; RuleNode *alert_node, *log_node, *counter_node; BOOL bMatch = FALSE; char src[32], dst[32], type[64]; char info[64], str[128], msg[128], numbytes[12]; unsigned short ptype; if (size < 42) // probably a corrupt packet return; size_framehdr = 14; src[0] = '\0'; dst[0] = '\0'; info[0] = '\0'; msg[0] = '\0'; wsprintf(numbytes, "%d", size); wsprintf(type, "Unknown"); eth = (struct ethernet_802_3 *) szBuffer; if (ntohs(eth->length) > 0x05DC) // its an ethernet_II frame { ptype = eth->length; /* length actually is type since its an eth_II frame */ size_framehdr = 14; } else // its an 802.3 frame { ptype = eth->type; size_framehdr = 22; } ptype = ntohs(ptype); /* if rules are NOT to be used, show all captured packets */ if (bFilter == FALSE) { GetPacketInfo(ptype, szBuffer, size_framehdr, src, dst, type, info); AddToAlert(rTime, szBuffer, size, src, dst, numbytes, type, info, ""); return; } if (ptype == 0x0800) { ip = (struct iphdr *) &szBuffer[size_framehdr]; size_iphdr = (ip->verlen & 0x0f) * 4; switch (ip->prot) { case R_ICMP: alert_node = root.alert.IcmpList; log_node = root.log.IcmpList; counter_node = root.counter.IcmpList; break; case R_UDP: alert_node = root.alert.UdpList; log_node = root.log.UdpList; counter_node = root.counter.UdpList; break; case R_TCP: alert_node = root.alert.TcpList; log_node = root.log.TcpList; counter_node = root.counter.TcpList; break; default: return; } /* check for match in the alert chain */ while (alert_node != NULL) { debug("checking alert node\r\n"); bMatch = MatchIpFields(alert_node, &szBuffer[size_framehdr]); if (bMatch) debug("ip header matches\r\n"); if (bMatch && alert_node->content_set) bMatch = MatchContent(&szBuffer[size_iphdr], size-size_iphdr, alert_node->content, lstrlen(alert_node->content)); if (bMatch) { GetPacketInfo(ptype, szBuffer, size_framehdr, src, dst, type, info); AddToAlert(rTime, szBuffer, size, src, dst, numbytes, type, info, alert_node->msg); break; } alert_node = alert_node->next; } /* check for match in the log chain */ while (log_node != NULL) { bMatch = MatchIpFields(log_node, &szBuffer[size_framehdr]); if (bMatch && log_node->content_set) bMatch = MatchContent(&szBuffer[size_iphdr], size-size_iphdr, log_node->content, lstrlen(log_node->content)); if (bMatch) { AddToLog(rTime, szBuffer, size, log_node->msg); break; } log_node = log_node->next; } /* check for all matches in the counter chain */ while (counter_node != NULL) { bMatch = MatchIpFields(counter_node, &szBuffer[size_framehdr]); if (bMatch && counter_node->content_set) bMatch = MatchContent(&szBuffer[size_iphdr], size-size_iphdr, counter_node->content, lstrlen(counter_node->content)); if (bMatch && counter_node->counter_id_set) { index = counter_node->counter_id; counter[index].count += 1; counter[index].bytes += size; wsprintf(str, "%d", counter[index].count); ListView_SetItemText(hWndCounterList, index, 2, str); FormatByteValue(counter[index].bytes, str); ListView_SetItemText(hWndCounterList, index, 3, str); } counter_node = counter_node->next; } } /* SPECIAL HANDLING FOR ARP PACKETS */ else if (ptype == 0x0806) { alert_node = root.alert.ArpList; if (alert_node != NULL) { GetPacketInfo(ptype, szBuffer, size_framehdr, src, dst, type, info); AddToAlert(rTime, szBuffer, size, src, dst, numbytes, type, info, alert_node->msg); } log_node = root.log.ArpList; if (log_node != NULL) { AddToLog(rTime, szBuffer, size, log_node->msg); } /* increment counter while here */ alert_node = root.counter.ArpList; if ((alert_node != NULL) && alert_node->counter_id_set) { index = alert_node->counter_id; counter[index].count += 1; counter[index].bytes += size; wsprintf(str, "%d", counter[index].count); ListView_SetItemText(hWndCounterList, index, 2, str); FormatByteValue(counter[index].bytes, str); ListView_SetItemText(hWndCounterList, index, 3, str); } arp = (struct arppkt *) &szBuffer[size_framehdr]; wsprintf(dst, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", arp->sender_ha[0], arp->sender_ha[1],arp->sender_ha[2],arp->sender_ha[3],arp->sender_ha[4],arp->sender_ha[5]); wsprintf(src, "%d.%d.%d.%d", arp->sender_ip[0], arp->sender_ip[1], arp->sender_ip[2], arp->sender_ip[3]); AddToARP(hWndARPList, src, dst); } }
OPENMPT_NAMESPACE_BEGIN bool CSoundFile::ReadMO3(FileReader &file, ModLoadingFlags loadFlags) //------------------------------------------------------------------- { file.Rewind(); // No valid MO3 file (magic bytes: "MO3") if(!file.CanRead(8) || !file.ReadMagic("MO3")) { return false; } else if(loadFlags == onlyVerifyHeader) { return true; } #ifdef NO_MO3 // As of November 2013, the format revision is 5; Versions > 31 are unlikely to exist in the next few years, // so we will just ignore those if there's no UNMO3 library to tell us if the file is valid or not // (avoid log entry with .MOD files that have a song name starting with "MO3". if(file.ReadUint8() > 31) { return false; } AddToLog(GetStrI18N("The file appears to be a MO3 file, but this OpenMPT build does not support loading MO3 files.")); return false; #else bool result = false; // Result of trying to load the module, false == fail. // Try to load unmo3 dynamically. mpt::Library unmo3 = mpt::Library(mpt::LibraryPath::App(MPT_PATHSTRING("unmo3"))); if(!unmo3.IsValid()) { // Didn't succeed. AddToLog(GetStrI18N("Loading MO3 file failed because unmo3.dll could not be loaded.")); } else { // Library loaded successfully. #if MPT_OS_WINDOWS #define UNMO3_API __stdcall #else #define UNMO3_API #endif typedef uint32 (UNMO3_API * UNMO3_GETVERSION)(); // Decode a MO3 file (returns the same "exit codes" as UNMO3.EXE, eg. 0=success) // IN: data/len = MO3 data/len // OUT: data/len = decoded data/len (if successful) // flags & 1: Don't load samples typedef int32 (UNMO3_API * UNMO3_DECODE_OLD)(const void **data, uint32 *len); typedef int32 (UNMO3_API * UNMO3_DECODE)(const void **data, uint32 *len, uint32 flags); // Free the data returned by UNMO3_Decode typedef void (UNMO3_API * UNMO3_FREE)(const void *data); #undef UNMO3_API UNMO3_GETVERSION UNMO3_GetVersion = nullptr; UNMO3_DECODE_OLD UNMO3_Decode_Old = nullptr; UNMO3_DECODE UNMO3_Decode = nullptr; UNMO3_FREE UNMO3_Free = nullptr; unmo3.Bind(UNMO3_GetVersion, "UNMO3_GetVersion"); if(UNMO3_GetVersion == nullptr) { // Old API version: No "flags" parameter. unmo3.Bind(UNMO3_Decode_Old, "UNMO3_Decode"); } else { unmo3.Bind(UNMO3_Decode, "UNMO3_Decode"); } unmo3.Bind(UNMO3_Free, "UNMO3_Free"); if((UNMO3_Decode != nullptr || UNMO3_Decode_Old != nullptr) && UNMO3_Free != nullptr) { file.Rewind(); const void *stream = file.GetRawData(); uint32 length = mpt::saturate_cast<uint32>(file.GetLength()); int32 unmo3result; if(UNMO3_Decode != nullptr) { unmo3result = UNMO3_Decode(&stream, &length, (loadFlags & loadSampleData) ? 0 : 1); } else { // Old API version: No "flags" parameter. unmo3result = UNMO3_Decode_Old(&stream, &length); } if(unmo3result == 0) { // If decoding was successful, stream and length will keep the new pointers now. FileReader unpackedFile(stream, length); result = ReadXM(unpackedFile, loadFlags) || ReadIT(unpackedFile, loadFlags) || ReadS3M(unpackedFile, loadFlags) || ReadMTM(unpackedFile, loadFlags) || ReadMod(unpackedFile, loadFlags) || ReadM15(unpackedFile, loadFlags); if(result) { m_ContainerType = MOD_CONTAINERTYPE_MO3; } UNMO3_Free(stream); } } } return result; #endif // NO_MO3 }