static unsigned int inline flac_get_metablock_length(unsigned int data) { return LittleEndian(data) & 0x0FFF; }
// public int ReadInt() [instance] :134 int BinaryReader::ReadInt() { FillBuffer(4); return ::g::Uno::Runtime::Implementation::BufferImpl::GetInt(_buffer, 0, LittleEndian()); }
bool module_renderer::ReadITProject(const uint8_t * lpStream, const uint32_t dwMemLength) //----------------------------------------------------------------------- { UINT i,n,nsmp; uint32_t id,len,size; uint32_t dwMemPos = 0; uint32_t version; ASSERT_CAN_READ(12); // Check file ID memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); if(id != ITP_FILE_ID) return false; dwMemPos += sizeof(uint32_t); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); version = id; dwMemPos += sizeof(uint32_t); // bad_max supported version if(version > ITP_VERSION) { return false; } m_nType = MOD_TYPE_IT; // Song name // name string length memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); len = id; dwMemPos += sizeof(uint32_t); // name string ASSERT_CAN_READ(len); if (len <= MAX_SAMPLENAME) { assign_without_padding(this->song_name, reinterpret_cast<const char *>(lpStream + dwMemPos), len); dwMemPos += len; } else return false; // Song comments // comment string length ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); dwMemPos += sizeof(uint32_t); if(id > UINT16_MAX) return false; // allocate and copy comment string ASSERT_CAN_READ(id); if(id > 0) { ReadMessage(lpStream + dwMemPos, id - 1, leCR); } dwMemPos += id; // Song global config ASSERT_CAN_READ(5*4); // m_dwSongFlags memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_dwSongFlags = (id & SONG_FILE_FLAGS); dwMemPos += sizeof(uint32_t); if(!(m_dwSongFlags & SONG_ITPROJECT)) return false; // m_nDefaultGlobalVolume memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_nDefaultGlobalVolume = id; dwMemPos += sizeof(uint32_t); // m_nSamplePreAmp memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_nSamplePreAmp = id; dwMemPos += sizeof(uint32_t); // m_nDefaultSpeed memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_nDefaultSpeed = id; dwMemPos += sizeof(uint32_t); // m_nDefaultTempo memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_nDefaultTempo = id; dwMemPos += sizeof(uint32_t); // Song channels data ASSERT_CAN_READ(2*4); // m_nChannels memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_nChannels = (modplug::tracker::chnindex_t)id; dwMemPos += sizeof(uint32_t); if(m_nChannels > 127) return false; // channel name string length (=MAX_CHANNELNAME) memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); len = id; dwMemPos += sizeof(uint32_t); if(len > MAX_CHANNELNAME) return false; // Channels' data for(i=0; i<m_nChannels; i++){ ASSERT_CAN_READ(3*4 + len); // ChnSettings[i].nPan memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); ChnSettings[i].nPan = id; dwMemPos += sizeof(uint32_t); // ChnSettings[i].dwFlags memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); ChnSettings[i].dwFlags = id; dwMemPos += sizeof(uint32_t); // ChnSettings[i].nVolume memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); ChnSettings[i].nVolume = id; dwMemPos += sizeof(uint32_t); // ChnSettings[i].szName memcpy(&ChnSettings[i].szName[0],lpStream+dwMemPos,len); SetNullTerminator(ChnSettings[i].szName); dwMemPos += len; } // Song mix plugins // size of mix plugins data ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); dwMemPos += sizeof(uint32_t); // mix plugins ASSERT_CAN_READ(id); dwMemPos += LoadMixPlugins(lpStream+dwMemPos, id); // Song midi config // midi cfg data length ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); dwMemPos += sizeof(uint32_t); // midi cfg ASSERT_CAN_READ(id); if (id <= sizeof(m_MidiCfg)) { memcpy(&m_MidiCfg, lpStream + dwMemPos, id); SanitizeMacros(); dwMemPos += id; } // Song Instruments // m_nInstruments ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); m_nInstruments = (modplug::tracker::instrumentindex_t)id; if(m_nInstruments > MAX_INSTRUMENTS) return false; dwMemPos += sizeof(uint32_t); // path string length (=_MAX_PATH) ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); len = id; if(len > _MAX_PATH) return false; dwMemPos += sizeof(uint32_t); // instruments' paths for(i=0; i<m_nInstruments; i++){ ASSERT_CAN_READ(len); memcpy(&m_szInstrumentPath[i][0],lpStream+dwMemPos,len); SetNullTerminator(m_szInstrumentPath[i]); dwMemPos += len; } // Song Orders // size of order array (=MAX_ORDERS) ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); size = id; if(size > MAX_ORDERS) return false; dwMemPos += sizeof(uint32_t); // order data ASSERT_CAN_READ(size); Order.ReadAsByte(lpStream+dwMemPos, size, dwMemLength-dwMemPos); dwMemPos += size; // Song Patterns ASSERT_CAN_READ(3*4); // number of patterns (=MAX_PATTERNS) memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); size = id; dwMemPos += sizeof(uint32_t); if(size > MAX_PATTERNS) return false; // m_nPatternNames memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); const modplug::tracker::patternindex_t numNamedPats = id; dwMemPos += sizeof(uint32_t); // pattern name string length (=MAX_PATTERNNAME) memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); const uint32_t patNameLen = id; dwMemPos += sizeof(uint32_t); // m_lpszPatternNames ASSERT_CAN_READ(numNamedPats * patNameLen); char *patNames = (char *)(lpStream + dwMemPos); dwMemPos += numNamedPats * patNameLen; // modcommand data length ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); n = id; if(n != 6) return false; dwMemPos += sizeof(uint32_t); for(modplug::tracker::patternindex_t npat=0; npat<size; npat++) { // Patterns[npat].GetNumRows() ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); if(id > MAX_PATTERN_ROWS) return false; const modplug::tracker::rowindex_t nRows = id; dwMemPos += sizeof(uint32_t); // Try to allocate & read only sized patterns if(nRows) { // Allocate pattern if(Patterns.Insert(npat, nRows)) { dwMemPos += m_nChannels * Patterns[npat].GetNumRows() * n; continue; } if(npat < numNamedPats && patNameLen > 0) { Patterns[npat].SetName(patNames, patNameLen); patNames += patNameLen; } // Pattern data long datasize = m_nChannels * Patterns[npat].GetNumRows() * n; //if (streamPos+datasize<=dwMemLength) { if(Patterns[npat].ReadITPdata(lpStream, dwMemPos, datasize, dwMemLength)) { ErrorBox(IDS_ERR_FILEOPEN, NULL); return false; } //memcpy(Patterns[npat],lpStream+streamPos,datasize); //streamPos += datasize; //} } } // Load embeded samples ITSAMPLESTRUCT pis; // Read original number of samples ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); if(id > MAX_SAMPLES) return false; m_nSamples = (modplug::tracker::sampleindex_t)id; dwMemPos += sizeof(uint32_t); // Read number of embeded samples ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); if(id > MAX_SAMPLES) return false; n = id; dwMemPos += sizeof(uint32_t); // Read samples for(i=0; i<n; i++){ ASSERT_CAN_READ(4 + sizeof(ITSAMPLESTRUCT) + 4); // Sample id number memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); nsmp = id; dwMemPos += sizeof(uint32_t); if(nsmp < 1 || nsmp >= MAX_SAMPLES) return false; // Sample struct memcpy(&pis,lpStream+dwMemPos,sizeof(ITSAMPLESTRUCT)); dwMemPos += sizeof(ITSAMPLESTRUCT); // Sample length memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t)); len = id; dwMemPos += sizeof(uint32_t); if(dwMemPos >= dwMemLength || len > dwMemLength - dwMemPos) return false; // Copy sample struct data (ut-oh... this code looks very familiar!) if(pis.id == LittleEndian(IT_IMPS)) { modsample_t *pSmp = &Samples[nsmp]; memcpy(pSmp->legacy_filename, pis.filename, 12); pSmp->flags = 0; pSmp->length = 0; pSmp->loop_start = pis.loopbegin; pSmp->loop_end = pis.loopend; pSmp->sustain_start = pis.susloopbegin; pSmp->sustain_end = pis.susloopend; pSmp->c5_samplerate = pis.C5Speed; if(!pSmp->c5_samplerate) pSmp->c5_samplerate = 8363; if(pis.C5Speed < 256) pSmp->c5_samplerate = 256; pSmp->default_volume = pis.vol << 2; if(pSmp->default_volume > 256) pSmp->default_volume = 256; pSmp->global_volume = pis.gvl; if(pSmp->global_volume > 64) pSmp->global_volume = 64; if(pis.flags & 0x10) pSmp->flags |= CHN_LOOP; if(pis.flags & 0x20) pSmp->flags |= CHN_SUSTAINLOOP; if(pis.flags & 0x40) pSmp->flags |= CHN_PINGPONGLOOP; if(pis.flags & 0x80) pSmp->flags |= CHN_PINGPONGSUSTAIN; pSmp->default_pan = (pis.dfp & 0x7F) << 2; if(pSmp->default_pan > 256) pSmp->default_pan = 256; if(pis.dfp & 0x80) pSmp->flags |= CHN_PANNING; pSmp->vibrato_type = autovibit2xm[pis.vit & 7]; pSmp->vibrato_rate = pis.vis; pSmp->vibrato_depth = pis.vid & 0x7F; pSmp->vibrato_sweep = pis.vir; if(pis.length){ pSmp->length = pis.length; if (pSmp->length > MAX_SAMPLE_LENGTH) pSmp->length = MAX_SAMPLE_LENGTH; UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U; if (pis.flags & 2){ flags += 5; if (pis.flags & 4) flags |= RSF_STEREO; pSmp->flags |= CHN_16BIT; } else{ if (pis.flags & 4) flags |= RSF_STEREO; } // Read sample data ReadSample(&Samples[nsmp], flags, (LPSTR)(lpStream+dwMemPos), len); dwMemPos += len; memcpy(m_szNames[nsmp], pis.name, 26); } } } // Load instruments CMappedFile f; LPBYTE lpFile; for(modplug::tracker::instrumentindex_t i = 0; i < m_nInstruments; i++) { if(m_szInstrumentPath[i][0] == '\0' || !f.Open(m_szInstrumentPath[i])) continue; len = f.GetLength(); lpFile = f.Lock(len); if(!lpFile) { f.Close(); continue; } ReadInstrumentFromFile(i+1, lpFile, len); f.Unlock(); f.Close(); } // Extra info data __int32 fcode = 0; const uint8_t * ptr = lpStream + bad_min(dwMemPos, dwMemLength); if (dwMemPos <= dwMemLength - 4) { fcode = (*((__int32 *)ptr)); } // Embed instruments' header [v1.01] if(version >= 0x00000101 && m_dwSongFlags & SONG_ITPEMBEDIH && fcode == 'EBIH') { // jump embeded instrument header tag ptr += sizeof(__int32); // set first instrument's header as current i = 1; // parse file while( uintptr_t(ptr - lpStream) <= dwMemLength - 4 && i <= m_nInstruments ) { fcode = (*((__int32 *)ptr)); // read field code switch( fcode ) { case 'MPTS': goto mpts; //:) // reached end of instrument headers case 'SEP@': case 'MPTX': ptr += sizeof(__int32); // jump code i++; // switch to next instrument break; default: ptr += sizeof(__int32); // jump field code ReadExtendedInstrumentProperty(Instruments[i], fcode, ptr, lpStream + dwMemLength); break; } } } //HACK: if we fail on i <= m_nInstruments above, arrive here without having set fcode as appropriate, // hence the code duplication. if ( (uintptr_t)(ptr - lpStream) <= dwMemLength - 4 ) { fcode = (*((__int32 *)ptr)); } // Song extensions mpts: if( fcode == 'MPTS' ) LoadExtendedSongProperties(MOD_TYPE_IT, ptr, lpStream, dwMemLength); m_nMaxPeriod = 0xF000; m_nMinPeriod = 8; if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50)) { SetModFlag(MSF_COMPATIBLE_PLAY, false); SetModFlag(MSF_MIDICC_BUGEMULATION, true); SetModFlag(MSF_OLDVOLSWING, true); } return true; }
bool module_renderer::SaveITProject(LPCSTR lpszFileName) //------------------------------------------------- { // Check song type if(!(m_dwSongFlags & SONG_ITPROJECT)) return false; UINT i,j = 0; for(i = 0 ; i < m_nInstruments ; i++) { if(m_szInstrumentPath[i][0] != '\0' || !Instruments[i+1]) j++; } if(m_nInstruments && j != m_nInstruments) return false; // Open file FILE *f; if((!lpszFileName) || ((f = fopen(lpszFileName, "wb")) == NULL)) return false; // File ID uint32_t id = ITP_FILE_ID; fwrite(&id, 1, sizeof(id), f); id = ITP_VERSION; fwrite(&id, 1, sizeof(id), f); // Song name // name string length id = 27; fwrite(&id, 1, sizeof(id), f); // song name char namebuf[27]; copy_with_padding(namebuf, 27, this->song_name); fwrite(namebuf, 1, 27, f); // Song comments // comment string length id = m_lpszSongComments ? strlen(m_lpszSongComments)+1 : 0; fwrite(&id, 1, sizeof(id), f); // comment string if(m_lpszSongComments) fwrite(&m_lpszSongComments[0], 1, strlen(m_lpszSongComments)+1, f); // Song global config id = (m_dwSongFlags & SONG_FILE_FLAGS); fwrite(&id, 1, sizeof(id), f); id = m_nDefaultGlobalVolume; fwrite(&id, 1, sizeof(id), f); id = m_nSamplePreAmp; fwrite(&id, 1, sizeof(id), f); id = m_nDefaultSpeed; fwrite(&id, 1, sizeof(id), f); id = m_nDefaultTempo; fwrite(&id, 1, sizeof(id), f); // Song channels data // number of channels id = m_nChannels; fwrite(&id, 1, sizeof(id), f); // channel name string length id = MAX_CHANNELNAME; fwrite(&id, 1, sizeof(id), f); // channel config data for(i=0; i<m_nChannels; i++){ id = ChnSettings[i].nPan; fwrite(&id, 1, sizeof(id), f); id = ChnSettings[i].dwFlags; fwrite(&id, 1, sizeof(id), f); id = ChnSettings[i].nVolume; fwrite(&id, 1, sizeof(id), f); fwrite(&ChnSettings[i].szName[0], 1, MAX_CHANNELNAME, f); } // Song mix plugins // mix plugins data length id = SaveMixPlugins(NULL, TRUE); fwrite(&id, 1, sizeof(id), f); // mix plugins data SaveMixPlugins(f, FALSE); // Song midi config // midi cfg data length id = sizeof(MODMIDICFG); fwrite(&id, 1, sizeof(id), f); // midi cfg fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); // Song Instruments // number of instruments id = m_nInstruments; fwrite(&id, 1, sizeof(id), f); // path name string length id = _MAX_PATH; fwrite(&id, 1, sizeof(id), f); // instruments' path for(i=0; i<m_nInstruments; i++) fwrite(&m_szInstrumentPath[i][0], 1, _MAX_PATH, f); // Song Orders // order array size id = Order.size(); fwrite(&id, 1, sizeof(id), f); // order array Order.WriteAsByte(f, id); // Song Patterns // number of patterns id = MAX_PATTERNS; fwrite(&id, 1, sizeof(id), f); // number of pattern name strings modplug::tracker::patternindex_t numNamedPats = Patterns.GetNumNamedPatterns(); numNamedPats = bad_min(numNamedPats, MAX_PATTERNS); id = numNamedPats; fwrite(&id, 1, sizeof(id), f); // length of a pattern name string id = MAX_PATTERNNAME; fwrite(&id, 1, sizeof(id), f); // pattern name string for(modplug::tracker::patternindex_t nPat = 0; nPat < numNamedPats; nPat++) { char name[MAX_PATTERNNAME]; MemsetZero(name); Patterns[nPat].GetName(name, MAX_PATTERNNAME); fwrite(name, 1, MAX_PATTERNNAME, f); } // modcommand data length id = sizeof(modplug::tracker::modevent_t); fwrite(&id, 1, sizeof(id), f); // patterns data content for(UINT npat=0; npat<MAX_PATTERNS; npat++){ // pattern size (number of rows) id = Patterns[npat] ? Patterns[npat].GetNumRows() : 0; fwrite(&id, 1, sizeof(id), f); // pattern data if(Patterns[npat] && Patterns[npat].GetNumRows()) Patterns[npat].WriteITPdata(f); //fwrite(Patterns[npat], 1, m_nChannels * Patterns[npat].GetNumRows() * sizeof(modplug::tracker::modcommand_t), f); } // Song lonely (instrument-less) samples // Write original number of samples id = m_nSamples; fwrite(&id, 1, sizeof(id), f); vector<bool> sampleUsed(m_nSamples, false); // Mark samples used in instruments for(i=0; i<m_nInstruments; i++) { if(Instruments[i + 1] != nullptr) { modinstrument_t *p = Instruments[i + 1]; for(j = 0; j < 128; j++) { if(p->Keyboard[j] > 0 && p->Keyboard[j] <= m_nSamples) sampleUsed[p->Keyboard[j] - 1] = true; } } } // Count samples not used in any instrument i = 0; for(j = 1; j <= m_nSamples; j++) if(!sampleUsed[j - 1] && Samples[j].sample_data) i++; id = i; fwrite(&id, 1, sizeof(id), f); // Write samples not used in any instrument (help, this looks like duplicate code!) ITSAMPLESTRUCT itss; for(UINT nsmp=1; nsmp<=m_nSamples; nsmp++) { if(!sampleUsed[nsmp - 1] && Samples[nsmp].sample_data) { modsample_t *psmp = &Samples[nsmp]; memset(&itss, 0, sizeof(itss)); memcpy(itss.filename, psmp->legacy_filename, 12); memcpy(itss.name, m_szNames[nsmp], 26); itss.id = LittleEndian(IT_IMPS); itss.gvl = (uint8_t)psmp->global_volume; itss.flags = 0x00; if(psmp->flags & CHN_LOOP) itss.flags |= 0x10; if(psmp->flags & CHN_SUSTAINLOOP) itss.flags |= 0x20; if(psmp->flags & CHN_PINGPONGLOOP) itss.flags |= 0x40; if(psmp->flags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; itss.C5Speed = psmp->c5_samplerate; if (!itss.C5Speed) itss.C5Speed = 8363; itss.length = psmp->length; itss.loopbegin = psmp->loop_start; itss.loopend = psmp->loop_end; itss.susloopbegin = psmp->sustain_start; itss.susloopend = psmp->sustain_end; itss.vol = (uint8_t)(psmp->default_volume >> 2); itss.dfp = (uint8_t)(psmp->default_pan >> 2); itss.vit = autovibxm2it[psmp->vibrato_type & 7]; itss.vis = bad_min(psmp->vibrato_rate, 64); itss.vid = bad_min(psmp->vibrato_depth, 32); itss.vir = bad_min(psmp->vibrato_sweep, 255); //(psmp->vibrato_sweep < 64) ? psmp->vibrato_sweep * 4 : 255; if (psmp->flags & CHN_PANNING) itss.dfp |= 0x80; if ((psmp->sample_data) && (psmp->length)) itss.cvt = 0x01; UINT flags = RS_PCM8S; if(psmp->flags & CHN_STEREO) { flags = RS_STPCM8S; itss.flags |= 0x04; } if(psmp->flags & CHN_16BIT) { itss.flags |= 0x02; flags = (psmp->flags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S; } id = nsmp; fwrite(&id, 1, sizeof(id), f); itss.samplepointer = NULL; fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f); id = WriteSample(NULL, psmp, flags); fwrite(&id, 1, sizeof(id), f); WriteSample(f, psmp, flags); } }
bool PtexReader::open(const char* path, Ptex::String& error) { if (!LittleEndian()) { error = "Ptex library doesn't currently support big-endian cpu's"; return 0; } _path = path; _fp = _io->open(path); if (!_fp) { std::string errstr = "Can't open ptex file: "; errstr += path; errstr += "\n"; errstr += _io->lastError(); error = errstr.c_str(); return 0; } readBlock(&_header, HeaderSize); if (_header.magic != Magic) { std::string errstr = "Not a ptex file: "; errstr += path; error = errstr.c_str(); return 0; } if (_header.version != 1) { char ver[21]; snprintf(ver, 20, "%d", _header.version); std::string errstr = "Unsupported ptex file version ("; errstr += ver; errstr += "): "; errstr += path; error = errstr.c_str(); return 0; } _pixelsize = _header.pixelSize(); // read extended header memset(&_extheader, 0, sizeof(_extheader)); readBlock(&_extheader, PtexUtils::min(uint32_t(ExtHeaderSize), _header.extheadersize)); // compute offsets of various blocks FilePos pos = tell(); _faceinfopos = pos; pos += _header.faceinfosize; _constdatapos = pos; pos += _header.constdatasize; _levelinfopos = pos; pos += _header.levelinfosize; _leveldatapos = pos; pos += _header.leveldatasize; _metadatapos = pos; pos += _header.metadatazipsize; pos += sizeof(uint64_t); // compatibility barrier _lmdheaderpos = pos; pos += _extheader.lmdheaderzipsize; _lmddatapos = pos; pos += _extheader.lmddatasize; // edit data may not start immediately if additional sections have been added // use value from extheader if present (and > pos) _editdatapos = PtexUtils::max(FilePos(_extheader.editdatapos), pos); // read basic file info readFaceInfo(); readConstData(); readLevelInfo(); readEditData(); // an error occurred while reading the file if (!_ok) { error = _error.c_str(); return 0; } return 1; }
void Check(unsigned Type, void* Float, void* Text) /* Type: 0 for float, 1 for double */ { unsigned i = { 0 }; unsigned char* b = { 0 }; unsigned char* c = { 0 }; /* We don't bother freeing this. */ const char* String = M3toC__SharedTtoS(Text); /* Change the indices to always print the bytes in little endian order, for portable output. */ unsigned x = (LittleEndian() ? 0 : (Type ? 7 : 3)); if (sizeof(float) != 4) { printf("double not 8 bytes\n"); exit(EXIT_FAILURE); } if (sizeof(double) != 8) { printf("double not 8 bytes\n"); exit(EXIT_FAILURE); } b = (unsigned char*) Float; String += strspn(String, " "); for (i = 0 ; Strings[i] ; ++i) { if (strcmp(String, Strings[i]) == 0) { c = (unsigned char*) (Type ? &Doubles[i] : (void*) &Floats[i]); if (memcmp(b, c, (Type ? sizeof(double) : sizeof(float))) != 0) { if (Type) { printf("double mismatch string %s test %x Modula-3 value %f C value %f Modula-3 bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", String, i, (*(double*) Float), Doubles[i], b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x], b[4 ^ x], b[5 ^ x], b[6 ^ x], b[7 ^ x], c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x], c[4 ^ x], c[5 ^ x], c[6 ^ x], c[7 ^ x]); } else { printf("float mismatch string %s test %x Modula-3 value %f C value %f Modula-3 bytes 0x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x\n", String, i, (*(float*) Float), Floats[i], b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x], c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x]); exit(EXIT_FAILURE); } } else { if (Type) { printf("double match string %s test %x Modula-3 value %f C value %f bytes Modula-3 bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", String, i, (*(double*) Float), Doubles[i], b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x], b[4 ^ x], b[5 ^ x], b[6 ^ x], b[7 ^ x], c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x], c[4 ^ x], c[5 ^ x], c[6 ^ x], c[7 ^ x]); } else { printf("float match string %s test %x Modula-3 value %f C value %f Modula-3 bytes 0x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x\n", String, i, (*(float*) Float), Floats[i], b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x], c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x]); } } fflush(stdout); return; } } printf("string not found %s\n", (Type ? "double" : "float", String)); exit(EXIT_FAILURE); }
/* Load BMF file format, function return bitmap font descriptor */ int glfLoadBMFFont(char *FName) { FILE *f; char Header[4]; char FontName[97]; int i, flag; int LEndian; float tx, ty, tw, th; unsigned char temp, *tp; unsigned *texture; /* Texture image */ unsigned *mask; /* Mask texture */ int twidth, theight, tcomp; /* Image parameters */ float *temp_width; LEndian = LittleEndian(); fopen_s(&f, FName, "rb"); if (f == NULL) return GLF_ERROR; /* Error opening file */ /* Get header */ fread(Header, 1, 3, f); Header[3] = 0; if (strcmp(Header, "BMF")) return GLF_ERROR; /* Not BMF format */ /* Get font name */ fread(FontName, 1, 96, f); FontName[96] = 0; /* Allocate space for temp widths */ temp_width = (float *)malloc(sizeof(float)*256); /* Read all 256 symbols information */ for (i=0; i<256; i++) { fread(&tx, 4, 1, f); fread(&ty, 4, 1, f); fread(&tw, 4, 1, f); fread(&th, 4, 1, f); if (!LEndian) { tp = (unsigned char *)&tx; temp = tp[0]; tp[0] = tp[3]; tp[3] = temp; temp = tp[1]; tp[1] = tp[2]; tp[2] = temp; tp = (unsigned char *)&ty; temp = tp[0]; tp[0] = tp[3]; tp[3] = temp; temp = tp[1]; tp[1] = tp[2]; tp[2] = temp; tp = (unsigned char *)&tw; temp = tp[0]; tp[0] = tp[3]; tp[3] = temp; temp = tp[1]; tp[1] = tp[2]; tp[2] = temp; tp = (unsigned char *)&th; temp = tp[0]; tp[0] = tp[3]; tp[3] = temp; temp = tp[1]; tp[1] = tp[2]; tp[2] = temp; } Symbols[i].x = tx; Symbols[i].y = ty; Symbols[i].width = tw; Symbols[i].height = th; temp_width[i] = tw; } /* Read texture image from file and build texture */ texture = read_texture(f, &twidth, &theight, &tcomp); /* Generate mask texture */ mask = texture_to_mask(texture, twidth, theight); /* Find unused font descriptor */ flag = 0; for (i=0; i<MAX_FONTS; i++) if (bmf_in_use[i] == 0) { /* Initialize this font */ bmf_in_use[i] = 1; bmf_curfont = i; flag = 1; break; } if (!flag) /* Not enought space for new texture */ { fclose(f); free(texture); free(mask); free(temp_width); return -1; } m_widths[bmf_curfont].width = temp_width; /* Generating textures for font and mask */ glGenTextures(1, &bmf_texture[bmf_curfont]); glGenTextures(1, &bmf_mask[bmf_curfont]); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* Build font texture */ glBindTexture(GL_TEXTURE_2D, bmf_texture[bmf_curfont]); glTexImage2D(GL_TEXTURE_2D, 0, 3, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); /* Linear filtering for better quality */ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* Build mask texture */ glBindTexture(GL_TEXTURE_2D, bmf_mask[bmf_curfont]); glTexImage2D(GL_TEXTURE_2D, 0, 3, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mask); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); free(texture); free(mask); fclose(f); /* Now build list for each symbol */ list_base[bmf_curfont] = glGenLists(256); for (i=0; i<256; i++) { glNewList(list_base[bmf_curfont]+i, GL_COMPILE); glBegin(GL_QUADS); glTexCoord2f(Symbols[i].x, Symbols[i].y); glVertex2f(0, 0); glTexCoord2f(Symbols[i].x+Symbols[i].width, Symbols[i].y); glVertex2f(Symbols[i].width, 0); glTexCoord2f(Symbols[i].x+Symbols[i].width, Symbols[i].y+Symbols[i].height); glVertex2f(Symbols[i].width, Symbols[i].height); glTexCoord2f(Symbols[i].x, Symbols[i].y+Symbols[i].height); glVertex2f(0, Symbols[i].height); glEnd(); glTranslatef(Symbols[i].width+sym_space, 0, 0); glEndList(); if (Symbols[i].height > m_max_height[bmf_curfont]) m_max_height[bmf_curfont] = Symbols[i].height; } return bmf_curfont; }
bool Chunk::loadFromFile() { m_Volume->incStatistic(STATISTIC_CHUNK_LOAD_OPS); m_Volume->log(VMAN_LOG_DEBUG, "Loading chunk %s from file ..\n", toString().c_str()); if(m_Volume->getBaseDir() == NULL) { assert(!"Probably redundant."); return false; } const int voxelsPerChunk = m_Volume->getVoxelsPerChunk(); std::string fileName = m_Volume->getChunkFileName(m_ChunkX, m_ChunkY, m_ChunkZ); FILE* f = fopen(fileName.c_str(), "rb"); if(f == NULL) { m_Volume->log(VMAN_LOG_DEBUG, "%s: File does not exist.\n", fileName.c_str()); return false; } try { // -- Read header -- ChunkFileHeader header; if(fread(&header, sizeof(header), 1, f) != 1) throw "Read error in file header."; header.version = LittleEndian(header.version); header.edgeLength = LittleEndian(header.edgeLength); header.layerCount = LittleEndian(header.layerCount); m_Volume->log(VMAN_LOG_DEBUG, "version: %d\n", header.version); m_Volume->log(VMAN_LOG_DEBUG, "edgeLength: %d\n", header.edgeLength); m_Volume->log(VMAN_LOG_DEBUG, "layerCount: %d\n", header.layerCount); if(header.version != ChunkFileVersion) throw "Incorrect file version."; std::vector<ChunkFileLayerInfo> layerInfos(header.layerCount); // -- Read layer list -- for(int i = 0; i < layerInfos.size(); ++i) { ChunkFileLayerInfo* layerInfo = &layerInfos[i]; if(fread(layerInfo, sizeof(ChunkFileLayerInfo), 1, f) != 1) throw Format("Read error in layer info %d", i); layerInfo->voxelSize = LittleEndian(layerInfo->voxelSize); layerInfo->revision = LittleEndian(layerInfo->revision); layerInfo->fileOffset = LittleEndian(layerInfo->fileOffset); m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] name: '%s'\n", i, layerInfo->name); m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] voxelSize: %d\n", i, layerInfo->voxelSize); m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] revision: %d\n", i, layerInfo->revision); m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] fileOffset: %d\n", i, layerInfo->fileOffset); if(m_Volume->getLayerIndexByName(layerInfo->name) == -1) { m_Volume->log(VMAN_LOG_INFO, "%s: Ignoring chunk layer '%s'.\n", fileName.c_str(), layerInfo->name); } } // -- Copy used layers -- std::vector<char> buffer(voxelsPerChunk * m_Volume->getMaxLayerVoxelSize()); for(int i = 0; i < m_Layers.size(); ++i) { const vmanLayer* layer = m_Volume->getLayer(i); const ChunkFileLayerInfo* layerInfo = FindChunkLayerByName(layerInfos, layer->name); if(layerInfo) { if( (layer->voxelSize != layerInfo->voxelSize) || (layer->revision != layerInfo->revision) ) { m_Volume->log(VMAN_LOG_ERROR,"%s: Chunk layer '%s' differs, ignoring it.\n", fileName.c_str(), layer->name); // TODO: Maybe let the application try to import/convert the layer. continue; } fseek(f, layerInfo->fileOffset, SEEK_SET); if(fread(&buffer[0], voxelsPerChunk*layer->voxelSize, 1, f) != 1) throw Format("Read error in layer %d.", i); m_Layers[i] = new char[voxelsPerChunk*layer->voxelSize]; layer->deserializeFn(&buffer[0], m_Layers[i], voxelsPerChunk*layer->voxelSize); } } } catch(const std::string e) { m_Volume->log(VMAN_LOG_ERROR, "%s: %s\n", fileName.c_str(), e.c_str()); fclose(f); clearLayers(); assert(false); return false; } fclose(f); return true; }
// // Read double float from (little-endian) database binary file // Automatically adjusts for big-endian processors // void ReadDouble (PODFILE *f, double *pData) { pread (pData, sizeof(double), 1, f); *pData = LittleEndian(*pData); }
// // Read float from (little-endian) database binary file // Automatically adjusts for big-endian processors // void ReadFloat (PODFILE *f, float *pData) { pread (pData, sizeof(float), 1, f); *pData = LittleEndian(*pData); }
// // Read unsigned short from (little-endian) database binary file // Automatically adjusts for big-endian processors // void ReadUShort (PODFILE *f, unsigned short *pData) { pread (pData, sizeof(unsigned short), 1, f); *pData = LittleEndian(*pData); }
// // Read signed long from binary file // void ReadLong (PODFILE *f, long *pData) { pread (pData, sizeof(long), 1, f); *pData = LittleEndian(*pData); }
// // Read unsigned long from binary file // void ReadULong (PODFILE *f, unsigned long *pData) { pread (pData, sizeof(unsigned long), 1, f); *pData = LittleEndian(*pData); }
// public BinaryWriter(Uno.IO.Stream stream) [instance] :371 void BinaryWriter::ctor_(::g::Uno::IO::Stream* stream) { _stream = stream; _buffer = uArray::New(::TYPES[0/*byte[]*/], 64); LittleEndian(true); }
/* | This function read font file and store information in memory | Return: GLF_OK - if all OK | Return: GLF_ERROR - if any error */ static int ReadFont(char *font_name, struct glf_font *glff) { FILE *fontf; char buffer[64]; int i, j; unsigned char temp, code, verts, fcets, lns; float tempfx, tempfy; unsigned char *tp; int LEndian; /* True if little endian machine */ fopen_s(&fontf, font_name, "rb"); if (fontf == NULL) return GLF_ERROR; fread(buffer, 3, 1, fontf); buffer[3] = 0; if (strcmp(buffer, "GLF")) { /* If header is not "GLF" */ if (console_msg) printf("Error reading font file: incorrect file format\n"); return GLF_ERROR; } /* Check for machine type */ LEndian = LittleEndian(); fread(glff->font_name, 96, 1, fontf); glff->font_name[96] = 0; fread(&glff->sym_total, 1, 1, fontf); /* Read total symbols in font */ for (i=0; i<MAX_FONTS; i++) glff->symbols[i] = NULL; for (i=0; i<28; i++) fread(&temp, 1, 1, fontf); /* Read unused data */ /* Now start to read font data */ for (i=0; i<glff->sym_total; i++) { fread(&code, 1, 1, fontf); /* Read symbol code */ fread(&verts, 1, 1, fontf); /* Read vertexs count */ fread(&fcets, 1, 1, fontf); /* Read facets count */ fread(&lns, 1, 1, fontf); /* Read lines count */ if (glff->symbols[code] != NULL) { if (console_msg) printf("Error reading font file: encountered symbols in font\n"); return GLF_ERROR; } glff->symbols[code] = (struct one_symbol *)malloc(sizeof(struct one_symbol)); glff->symbols[code]->vdata = (float *)malloc(8*verts); glff->symbols[code]->fdata = (unsigned char *)malloc(3*fcets); glff->symbols[code]->ldata = (unsigned char *)malloc(lns); glff->symbols[code]->vertexs = verts; glff->symbols[code]->facets = fcets; glff->symbols[code]->lines = lns; /* Read vertexs data */ glff->symbols[code]->leftx = 10; glff->symbols[code]->rightx = -10; glff->symbols[code]->topy = 10; glff->symbols[code]->bottomy = -10; for (j=0; j<verts; j++) { fread(&tempfx, 4, 1, fontf); fread(&tempfy, 4, 1, fontf); /* If machine is bigendian -> swap low and high words in tempfx and tempfy */ if (!LEndian) { tp = (unsigned char *)&tempfx; temp = tp[0]; tp[0] = tp[3]; tp[3] = temp; temp = tp[1]; tp[1] = tp[2]; tp[2] = temp; tp = (unsigned char *)&tempfy; temp = tp[0]; tp[0] = tp[3]; tp[3] = temp; temp = tp[1]; tp[1] = tp[2]; tp[2] = temp; } glff->symbols[code]->vdata[j*2] = tempfx; glff->symbols[code]->vdata[j*2+1] = tempfy; if (tempfx < glff->symbols[code]->leftx) glff->symbols[code]->leftx = tempfx; if (tempfx > glff->symbols[code]->rightx) glff->symbols[code]->rightx = tempfx; if (tempfy < glff->symbols[code]->topy) glff->symbols[code]->topy = tempfy; if (tempfy > glff->symbols[code]->bottomy) glff->symbols[code]->bottomy = tempfy; } for (j=0; j<fcets; j++) fread(&glff->symbols[code]->fdata[j*3], 3, 1, fontf); for (j=0; j<lns; j++) fread(&glff->symbols[code]->ldata[j], 1, 1, fontf); } fclose(fontf); return GLF_OK; }
// public void Write(int value) [instance] :434 void BinaryWriter::Write13(int value) { ::g::Uno::Runtime::Implementation::BufferImpl::SetInt(_buffer, 0, value, LittleEndian()); uPtr(_stream)->Write(_buffer, 0, 4); }
bool module_renderer::ReadXM(const uint8_t *lpStream, const uint32_t dwMemLength) //-------------------------------------------------------------------- { XMFILEHEADER xmheader; XMSAMPLEHEADER xmsh; XMSAMPLESTRUCT xmss; uint32_t dwMemPos; bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false, bProbablyMPT109 = false, bIsFT2 = false; m_nChannels = 0; if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false; // look for null-terminated song name - that's most likely a tune made with modplug for(int i = 0; i < 20; i++) if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true; assign_without_padding(this->song_name, reinterpret_cast<const char *>(lpStream + 17), 20); // load and convert header memcpy(&xmheader, lpStream + 58, sizeof(XMFILEHEADER)); xmheader.size = LittleEndian(xmheader.size); xmheader.xmversion = LittleEndianW(xmheader.xmversion); xmheader.orders = LittleEndianW(xmheader.orders); xmheader.restartpos = LittleEndianW(xmheader.restartpos); xmheader.channels = LittleEndianW(xmheader.channels); xmheader.patterns = LittleEndianW(xmheader.patterns); xmheader.instruments = LittleEndianW(xmheader.instruments); xmheader.flags = LittleEndianW(xmheader.flags); xmheader.speed = LittleEndianW(xmheader.speed); xmheader.tempo = LittleEndianW(xmheader.tempo); m_nType = MOD_TYPE_XM; m_nMinPeriod = 27; m_nMaxPeriod = 54784; if (xmheader.orders > MAX_ORDERS) return false; if ((!xmheader.channels) || (xmheader.channels > MAX_BASECHANNELS)) return false; if (xmheader.channels > 32) bMadeWithModPlug = true; m_nRestartPos = xmheader.restartpos; m_nChannels = xmheader.channels; m_nInstruments = bad_min(xmheader.instruments, MAX_INSTRUMENTS - 1); m_nSamples = 0; m_nDefaultSpeed = CLAMP(xmheader.speed, 1, 31); m_nDefaultTempo = CLAMP(xmheader.tempo, 32, 512); if(xmheader.flags & 1) m_dwSongFlags |= SONG_LINEARSLIDES; if(xmheader.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; Order.ReadAsByte(lpStream + 80, xmheader.orders, dwMemLength - 80); dwMemPos = xmheader.size + 60; // set this here already because XMs compressed with BoobieSqueezer will exit the function early SetModFlag(MSF_COMPATIBLE_PLAY, true); if(xmheader.xmversion >= 0x0104) { if (dwMemPos + 8 >= dwMemLength) return true; dwMemPos = ReadXMPatterns(lpStream, dwMemLength, dwMemPos, &xmheader, this); if(dwMemPos == 0) return true; } vector<bool> samples_used; // for removing unused samples modplug::tracker::sampleindex_t unused_samples = 0; // dito // Reading instruments for (modplug::tracker::instrumentindex_t iIns = 1; iIns <= m_nInstruments; iIns++) { XMINSTRUMENTHEADER pih; uint8_t flags[32]; uint32_t samplesize[32]; UINT samplemap[32]; uint16_t nsamples; if (dwMemPos + sizeof(uint32_t) >= dwMemLength) return true; uint32_t ihsize = LittleEndian(*((uint32_t *)(lpStream + dwMemPos))); if (dwMemPos + ihsize > dwMemLength) return true; MemsetZero(pih); memcpy(&pih, lpStream + dwMemPos, bad_min(sizeof(pih), ihsize)); if ((Instruments[iIns] = new modinstrument_t) == nullptr) continue; memcpy(Instruments[iIns], &m_defaultInstrument, sizeof(modinstrument_t)); Instruments[iIns]->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; Instruments[iIns]->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; memcpy(Instruments[iIns]->name, pih.name, 22); SpaceToNullStringFixed<22>(Instruments[iIns]->name); memset(&xmsh, 0, sizeof(XMSAMPLEHEADER)); if ((nsamples = pih.samples) > 0) { /* we have samples, so let's read the rest of this instrument the header that is being read here is not the sample header, though, it's rather the instrument settings. */ if (dwMemPos + ihsize >= dwMemLength) return true; memcpy(&xmsh, lpStream + dwMemPos + sizeof(XMINSTRUMENTHEADER), bad_min(ihsize - sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER))); xmsh.shsize = LittleEndian(xmsh.shsize); if(xmsh.shsize == 0 && bProbablyMadeWithModPlug) bMadeWithModPlug = true; for (int i = 0; i < 24; ++i) { xmsh.venv[i] = LittleEndianW(xmsh.venv[i]); xmsh.penv[i] = LittleEndianW(xmsh.penv[i]); } xmsh.volfade = LittleEndianW(xmsh.volfade); xmsh.midiprogram = LittleEndianW(xmsh.midiprogram); xmsh.pitchwheelrange = LittleEndianW(xmsh.pitchwheelrange); if(xmsh.midichannel != 0 || xmsh.midienabled != 0 || xmsh.midiprogram != 0 || xmsh.mutecomputer != 0 || xmsh.pitchwheelrange != 0) bIsFT2 = true; // definitely not MPT. (or any other tracker) } if (LittleEndian(pih.size)) dwMemPos += LittleEndian(pih.size); else dwMemPos += sizeof(XMINSTRUMENTHEADER); memset(samplemap, 0, sizeof(samplemap)); if (nsamples > 32) return true; UINT newsamples = m_nSamples; for (UINT nmap = 0; nmap < nsamples; nmap++) { UINT n = m_nSamples + nmap + 1; if (n >= MAX_SAMPLES) { n = m_nSamples; while (n > 0) { if (!Samples[n].sample_data) { for (UINT xmapchk=0; xmapchk < nmap; xmapchk++) { if (samplemap[xmapchk] == n) goto alreadymapped; } for (UINT clrs=1; clrs<iIns; clrs++) if (Instruments[clrs]) { modinstrument_t *pks = Instruments[clrs]; for (UINT ks=0; ks<128; ks++) { if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0; } } break; } alreadymapped: n--; } #ifndef FASTSOUNDLIB // Damn! Too many samples: look for duplicates if (!n) { if (!unused_samples) { unused_samples = DetectUnusedSamples(samples_used); if (!unused_samples) unused_samples = modplug::tracker::SampleIndexInvalid; } if ((unused_samples) && (unused_samples != modplug::tracker::SampleIndexInvalid)) { for (UINT iext=m_nSamples; iext>=1; iext--) if (!samples_used[iext]) { unused_samples--; samples_used[iext] = true; DestroySample(iext); n = iext; for (UINT mapchk=0; mapchk<nmap; mapchk++) { if (samplemap[mapchk] == n) samplemap[mapchk] = 0; } for (UINT clrs=1; clrs<iIns; clrs++) if (Instruments[clrs]) { modinstrument_t *pks = Instruments[clrs]; for (UINT ks=0; ks<128; ks++) { if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0; } } MemsetZero(Samples[n]); break; } } } #endif // FASTSOUNDLIB } if (newsamples < n) newsamples = n; samplemap[nmap] = n; } m_nSamples = newsamples; // Reading Volume Envelope modinstrument_t *pIns = Instruments[iIns]; pIns->midi_program = pih.type; pIns->fadeout = xmsh.volfade; pIns->default_pan = 128; pIns->pitch_pan_center = 5*12; SetDefaultInstrumentValues(pIns); pIns->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; pIns->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; if (xmsh.vtype & 1) pIns->volume_envelope.flags |= ENV_ENABLED; if (xmsh.vtype & 2) pIns->volume_envelope.flags |= ENV_SUSTAIN; if (xmsh.vtype & 4) pIns->volume_envelope.flags |= ENV_LOOP; if (xmsh.ptype & 1) pIns->panning_envelope.flags |= ENV_ENABLED; if (xmsh.ptype & 2) pIns->panning_envelope.flags |= ENV_SUSTAIN; if (xmsh.ptype & 4) pIns->panning_envelope.flags |= ENV_LOOP; if (xmsh.vnum > 12) xmsh.vnum = 12; if (xmsh.pnum > 12) xmsh.pnum = 12; pIns->volume_envelope.num_nodes = xmsh.vnum; if (!xmsh.vnum) pIns->volume_envelope.flags &= ~ENV_ENABLED; if (!xmsh.pnum) pIns->panning_envelope.flags &= ~ENV_ENABLED; pIns->panning_envelope.num_nodes = xmsh.pnum; pIns->volume_envelope.sustain_start = pIns->volume_envelope.sustain_end = xmsh.vsustain; if (xmsh.vsustain >= 12) pIns->volume_envelope.flags &= ~ENV_SUSTAIN; pIns->volume_envelope.loop_start = xmsh.vloops; pIns->volume_envelope.loop_end = xmsh.vloope; if (pIns->volume_envelope.loop_end >= 12) pIns->volume_envelope.loop_end = 0; if (pIns->volume_envelope.loop_start >= pIns->volume_envelope.loop_end) pIns->volume_envelope.flags &= ~ENV_LOOP; pIns->panning_envelope.sustain_start = pIns->panning_envelope.sustain_end = xmsh.psustain; if (xmsh.psustain >= 12) pIns->panning_envelope.flags &= ~ENV_SUSTAIN; pIns->panning_envelope.loop_start = xmsh.ploops; pIns->panning_envelope.loop_end = xmsh.ploope; if (pIns->panning_envelope.loop_end >= 12) pIns->panning_envelope.loop_end = 0; if (pIns->panning_envelope.loop_start >= pIns->panning_envelope.loop_end) pIns->panning_envelope.flags &= ~ENV_LOOP; pIns->global_volume = 64; for (UINT ienv=0; ienv<12; ienv++) { pIns->volume_envelope.Ticks[ienv] = (uint16_t)xmsh.venv[ienv*2]; pIns->volume_envelope.Values[ienv] = (uint8_t)xmsh.venv[ienv*2+1]; pIns->panning_envelope.Ticks[ienv] = (uint16_t)xmsh.penv[ienv*2]; pIns->panning_envelope.Values[ienv] = (uint8_t)xmsh.penv[ienv*2+1]; if (ienv) { if (pIns->volume_envelope.Ticks[ienv] < pIns->volume_envelope.Ticks[ienv-1]) { pIns->volume_envelope.Ticks[ienv] &= 0xFF; pIns->volume_envelope.Ticks[ienv] += pIns->volume_envelope.Ticks[ienv-1] & 0xFF00; if (pIns->volume_envelope.Ticks[ienv] < pIns->volume_envelope.Ticks[ienv-1]) pIns->volume_envelope.Ticks[ienv] += 0x100; } if (pIns->panning_envelope.Ticks[ienv] < pIns->panning_envelope.Ticks[ienv-1]) { pIns->panning_envelope.Ticks[ienv] &= 0xFF; pIns->panning_envelope.Ticks[ienv] += pIns->panning_envelope.Ticks[ienv-1] & 0xFF00; if (pIns->panning_envelope.Ticks[ienv] < pIns->panning_envelope.Ticks[ienv-1]) pIns->panning_envelope.Ticks[ienv] += 0x100; } } } for (UINT j=0; j<96; j++) { pIns->NoteMap[j+12] = j+1+12; if (xmsh.snum[j] < nsamples) pIns->Keyboard[j+12] = samplemap[xmsh.snum[j]]; } // Reading samples for (UINT ins=0; ins<nsamples; ins++) { if ((dwMemPos + sizeof(xmss) > dwMemLength) || (dwMemPos + xmsh.shsize > dwMemLength)) return true; memcpy(&xmss, lpStream + dwMemPos, sizeof(xmss)); xmss.samplen = LittleEndian(xmss.samplen); xmss.loopstart = LittleEndian(xmss.loopstart); xmss.looplen = LittleEndian(xmss.looplen); dwMemPos += sizeof(XMSAMPLESTRUCT); // was: dwMemPos += xmsh.shsize; (this fixes IFULOVE.XM) flags[ins] = (xmss.type & 0x10) ? RS_PCM16D : RS_PCM8D; if (xmss.type & 0x20) flags[ins] = (xmss.type & 0x10) ? RS_STPCM16D : RS_STPCM8D; samplesize[ins] = xmss.samplen; if (!samplemap[ins]) continue; if (xmss.type & 0x10) { xmss.looplen >>= 1; xmss.loopstart >>= 1; xmss.samplen >>= 1; } if (xmss.type & 0x20) { xmss.looplen >>= 1; xmss.loopstart >>= 1; xmss.samplen >>= 1; } if (xmss.samplen > MAX_SAMPLE_LENGTH) xmss.samplen = MAX_SAMPLE_LENGTH; if (xmss.loopstart >= xmss.samplen) xmss.type &= ~3; xmss.looplen += xmss.loopstart; if (xmss.looplen > xmss.samplen) xmss.looplen = xmss.samplen; if (!xmss.looplen) xmss.type &= ~3; UINT imapsmp = samplemap[ins]; memcpy(m_szNames[imapsmp], xmss.name, 22); SpaceToNullStringFixed<22>(m_szNames[imapsmp]); modsample_t *pSmp = &Samples[imapsmp]; pSmp->length = (xmss.samplen > MAX_SAMPLE_LENGTH) ? MAX_SAMPLE_LENGTH : xmss.samplen; pSmp->loop_start = xmss.loopstart; pSmp->loop_end = xmss.looplen; if (pSmp->loop_end > pSmp->length) pSmp->loop_end = pSmp->length; if (pSmp->loop_start >= pSmp->loop_end) { pSmp->loop_start = pSmp->loop_end = 0; } if (xmss.type & 3) pSmp->flags |= CHN_LOOP; if (xmss.type & 2) pSmp->flags |= CHN_PINGPONGLOOP; pSmp->default_volume = xmss.vol << 2; if (pSmp->default_volume > 256) pSmp->default_volume = 256; pSmp->global_volume = 64; if ((xmss.res == 0xAD) && (!(xmss.type & 0x30))) { flags[ins] = RS_ADPCM4; samplesize[ins] = (samplesize[ins]+1)/2 + 16; } pSmp->nFineTune = xmss.finetune; pSmp->RelativeTone = (int)xmss.relnote; pSmp->default_pan = xmss.pan; pSmp->flags |= CHN_PANNING; pSmp->vibrato_type = xmsh.vibtype; pSmp->vibrato_sweep = xmsh.vibsweep; pSmp->vibrato_depth = xmsh.vibdepth; pSmp->vibrato_rate = xmsh.vibrate; memcpy(pSmp->legacy_filename, xmss.name, 22); SpaceToNullStringFixed<21>(pSmp->legacy_filename); if ((xmss.type & 3) == 3) // MPT 1.09 and maybe newer / older versions set both flags for bidi loops bProbablyMPT109 = true; }
bool Chunk::saveToFile() { m_Volume->incStatistic(STATISTIC_CHUNK_SAVE_OPS); m_Volume->log(VMAN_LOG_DEBUG, "Saving chunk %s to file ..\n", toString().c_str()); if(m_Volume->getBaseDir() == NULL) { assert(!"Probably redundant."); return false; } assert(m_Layers.size() > 0); const int voxelsPerChunk = m_Volume->getVoxelsPerChunk(); std::string fileName = m_Volume->getChunkFileName(m_ChunkX, m_ChunkY, m_ChunkZ); MakePath(fileName.c_str()); FILE* f = fopen(fileName.c_str(), "wb"); // TODO: Check if(f == NULL) { m_Volume->log(VMAN_LOG_ERROR, "%s: Can't open file for writing.\n", fileName.c_str()); return false; } // -- Write header --- ChunkFileHeader header; header.version = LittleEndian( ChunkFileVersion ); header.edgeLength = LittleEndian( m_Volume->getChunkEdgeLength() ); int usedLayers = 0; for(int i = 0; i < m_Layers.size(); ++i) if(m_Layers[i] != NULL) ++usedLayers; header.layerCount = LittleEndian( usedLayers ); fwrite(&header, sizeof(header), 1, f); const uint32_t headerSize = sizeof(ChunkFileHeader) + sizeof(ChunkFileLayerInfo)*usedLayers; // -- Write layer list -- uint32_t fileOffset = headerSize; for(int i = 0; i < m_Layers.size(); ++i) { if(m_Layers[i] != NULL) { ChunkFileLayerInfo layerInfo; const vmanLayer* layer = m_Volume->getLayer(i); memset(layerInfo.name, 0, sizeof(layerInfo.name)); strncpy(layerInfo.name, layer->name, sizeof(layerInfo.name)-1); layerInfo.voxelSize = LittleEndian(layer->voxelSize); layerInfo.revision = LittleEndian(layer->revision); layerInfo.fileOffset = LittleEndian(fileOffset); fwrite(&layerInfo, sizeof(layerInfo), 1, f); // Calculate layer size fileOffset += voxelsPerChunk * layerInfo.voxelSize; } } // -- Write actual layers -- std::vector<char> buffer(voxelsPerChunk * m_Volume->getMaxLayerVoxelSize()); // TODO: This buffer could be thread local ... for(int i = 0; i < m_Layers.size(); ++i) { if(m_Layers[i] != NULL) { const vmanLayer* layer = m_Volume->getLayer(i); layer->serializeFn(m_Layers[i], &buffer[0], voxelsPerChunk); fwrite(&buffer[0], voxelsPerChunk*layer->voxelSize, 1, f); // TODO: Check } } fclose(f); unsetModified(); return true; }
// Read .XM patterns uint32_t ReadXMPatterns(const uint8_t *lpStream, uint32_t dwMemLength, uint32_t dwMemPos, XMFILEHEADER *xmheader, module_renderer *pSndFile) //------------------------------------------------------------------------------------------------------------------------- { uint8_t patterns_used[256]; uint8_t pattern_map[256]; memset(patterns_used, 0, sizeof(patterns_used)); if (xmheader->patterns > MAX_PATTERNS) { UINT i, j; for (i = 0; i < xmheader->orders; i++) { if (pSndFile->Order[i] < xmheader->patterns) patterns_used[pSndFile->Order[i]] = true; } j = 0; for (i = 0; i < 256; i++) { if (patterns_used[i]) pattern_map[i] = j++; } for (i = 0; i < 256; i++) { if (!patterns_used[i]) { pattern_map[i] = (j < MAX_PATTERNS) ? j : 0xFE; j++; } } for (i = 0; i < xmheader->orders; i++) { pSndFile->Order[i] = pattern_map[pSndFile->Order[i]]; } } else { for (UINT i = 0; i < 256; i++) pattern_map[i] = i; } if (dwMemPos + 8 >= dwMemLength) return dwMemPos; // Reading patterns for (UINT ipat = 0; ipat < xmheader->patterns; ipat++) { UINT ipatmap = pattern_map[ipat]; uint32_t dwSize = 0; uint16_t rows = 64, packsize = 0; dwSize = LittleEndian(*((uint32_t *)(lpStream + dwMemPos))); if(xmheader->xmversion == 0x0102) { rows = *((uint8_t *)(lpStream + dwMemPos + 5)) + 1; packsize = LittleEndianW(*((uint16_t *)(lpStream + dwMemPos + 6))); } else { rows = LittleEndianW(*((uint16_t *)(lpStream + dwMemPos + 5))); packsize = LittleEndianW(*((uint16_t *)(lpStream + dwMemPos + 7))); } if ((!rows) || (rows > MAX_PATTERN_ROWS)) rows = 64; if (dwMemPos + dwSize + 4 > dwMemLength) return 0; dwMemPos += dwSize; if (dwMemPos + packsize > dwMemLength) return 0; modplug::tracker::modevent_t *p; if (ipatmap < MAX_PATTERNS) { if(pSndFile->Patterns.Insert(ipatmap, rows)) return true; if (!packsize) continue; p = pSndFile->Patterns[ipatmap]; } else p = NULL; const uint8_t *src = lpStream+dwMemPos; UINT j=0; for (UINT row=0; row<rows; row++) { for (UINT chn=0; chn < xmheader->channels; chn++) { if ((p) && (j < packsize)) { uint8_t b = src[j++]; UINT vol = 0; if (b & 0x80) { if (b & 1) p->note = src[j++]; if (b & 2) p->instr = src[j++]; if (b & 4) vol = src[j++]; //XXXih: gross!! if (b & 8) p->command = (modplug::tracker::cmd_t) src[j++]; if (b & 16) p->param = src[j++]; } else { p->note = b; p->instr = src[j++]; vol = src[j++]; //XXXih: gross!! p->command = (modplug::tracker::cmd_t) src[j++]; p->param = src[j++]; } if (p->note == 97) p->note = NoteKeyOff; else if ((p->note) && (p->note < 97)) p->note += 12; if (p->command | p->param) pSndFile->ConvertModCommand(p); if (p->instr == 0xff) p->instr = 0; if ((vol >= 0x10) && (vol <= 0x50)) { p->volcmd = VolCmdVol; p->vol = vol - 0x10; } else if (vol >= 0x60) { UINT v = vol & 0xF0; vol &= 0x0F; p->vol = vol; switch(v) { // 60-6F: Volume Slide Down case 0x60: p->volcmd = VolCmdSlideDown; break; // 70-7F: Volume Slide Up: case 0x70: p->volcmd = VolCmdSlideUp; break; // 80-8F: Fine Volume Slide Down case 0x80: p->volcmd = VolCmdFineDown; break; // 90-9F: Fine Volume Slide Up case 0x90: p->volcmd = VolCmdFineUp; break; // A0-AF: Set Vibrato Speed case 0xA0: p->volcmd = VolCmdVibratoSpeed; break; // B0-BF: Vibrato case 0xB0: p->volcmd = VolCmdVibratoDepth; break; // C0-CF: Set Panning case 0xC0: p->volcmd = VolCmdPan; p->vol = (vol << 2) + 2; break; // D0-DF: Panning Slide Left case 0xD0: p->volcmd = VolCmdPanSlideLeft; break; // E0-EF: Panning Slide Right case 0xE0: p->volcmd = VolCmdPanSlideRight; break; // F0-FF: Tone Portamento case 0xF0: p->volcmd = VolCmdPortamento; break; } } p++; } else if (j < packsize) { uint8_t b = src[j++]; if (b & 0x80) { if (b & 1) j++; if (b & 2) j++; if (b & 4) j++; if (b & 8) j++; if (b & 16) j++; } else j += 4; } else break; } } dwMemPos += packsize; } return dwMemPos; }
bool CGzipArchive::ExtractFile() //------------------------------ { #define ASSERT_CAN_READ(x) \ if( dwMemPos > m_dwStreamLen || x > m_dwStreamLen - dwMemPos ) return false; if(!IsArchive()) return false; DWORD dwMemPos = 0; GZheader *pHeader = (GZheader *)m_lpStream; GZtrailer *pTrailer = (GZtrailer *)(m_lpStream + m_dwStreamLen - sizeof(GZtrailer)); dwMemPos += sizeof(GZheader); // Extra block present? (ignore) if(pHeader->flags & GZ_FEXTRA) { ASSERT_CAN_READ(sizeof(uint16_t)); uint16_t xlen = LittleEndianW(*((uint16_t *)m_lpStream + dwMemPos)); dwMemPos += sizeof(uint16_t); // We skip this. ASSERT_CAN_READ(xlen); dwMemPos += xlen; } // Filename present? (ignore) if(pHeader->flags & GZ_FNAME) { do { ASSERT_CAN_READ(1); } while (m_lpStream[dwMemPos++] != 0); } // Comment present? (ignore) if(pHeader->flags & GZ_FCOMMENT) { do { ASSERT_CAN_READ(1); } while (m_lpStream[dwMemPos++] != 0); } // CRC16 present? if(pHeader->flags & GZ_FHCRC) { ASSERT_CAN_READ(sizeof(uint16_t)); uint16_t crc16_h = LittleEndianW(*((uint16_t *)m_lpStream + dwMemPos)); uint16_t crc16_f = (uint16_t)(crc32(0, m_lpStream, dwMemPos) & 0xFFFF); dwMemPos += sizeof(uint16_t); if(crc16_h != crc16_f) return false; } // Well, this is a bit small when inflated. if(pTrailer->isize == 0) return false; // Check if the deflated data is a bit small as well. ASSERT_CAN_READ(sizeof(GZtrailer) + 1); // Clear the output buffer, if necessary. if(m_pOutputFile != nullptr) { delete[] m_pOutputFile; } DWORD destSize = LittleEndian(pTrailer->isize); m_pOutputFile = new Bytef[destSize]; if(m_pOutputFile == nullptr) return false; // Inflate! z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = m_dwStreamLen - (dwMemPos + sizeof(GZtrailer)); strm.next_in = &m_lpStream[dwMemPos]; if(inflateInit2(&strm, -15) != Z_OK) return false; strm.avail_out = destSize; strm.next_out = m_pOutputFile; int nRetVal = inflate(&strm, Z_NO_FLUSH); inflateEnd(&strm); // Everything went OK? Check return code, number of written bytes and CRC32. if(nRetVal == Z_STREAM_END && destSize == strm.total_out && LittleEndian(pTrailer->crc32) == crc32(0, m_pOutputFile, destSize)) { // Success! :) m_dwOutputLen = destSize; return true; } else { // Fail :( if(m_pOutputFile != nullptr) { delete[] m_pOutputFile; } m_pOutputFile = nullptr; m_lpStream = nullptr; return false; } #undef ASSERT_CAN_READ }
bool CEndian::BigEndian() { return(!LittleEndian()); }