/* parse PARAM tag content: " NAME=... VALUE=... " */ static int ParseParam(NString *param, char **name_ret, char **value_ret) { NString word, name, value; char *stream = param->ptr; char *limit = param->ptr + param->length; /* look for the name part */ do stream = NextChunk(stream, limit, &word); while (word.length < 5 && memcmp("NAME=", word.ptr, 5 != 0) && *stream); if (stream == limit) return 1; name.ptr = word.ptr + 5; name.length = word.length - 5; *name_ret = GetLiteralValue(&name); /* look for the value part */ do stream = NextChunk(stream, limit, &word); while (word.length < 6 && memcmp("VALUE=", word.ptr, 6) != 0 && *stream); value.ptr = word.ptr + 6; value.length = word.length - 6; *value_ret = GetLiteralValue(&value); return 0; }
ResourceReader::ResourceReader(InputResource *resource, int bufferSize) : m_resource(resource), m_bufferIndex(0), m_bufferSize(bufferSize), m_bytesLeft(resource->GetLength()), m_bytesLeftInBuffer(0) { m_buffer = new char[m_bufferSize]; NextChunk(); }
void ResourceReader::Next() { if(m_bytesLeftInBuffer <= 0) { NextChunk(); } --m_bytesLeftInBuffer; ++m_bufferIndex; }
char ResourceReader::Char() { if(m_bytesLeftInBuffer <= 0) { NextChunk(); } --m_bytesLeftInBuffer; return m_buffer[m_bufferIndex++]; }
BOOL C4Playback::ExecuteControl(C4Control *pCtrl, int iFrame) { // still playbacking? if (currChunk == chunks.end()) return FALSE; if (Finished) { Finish(); return FALSE; } #ifdef DEBUGREC if (DebugRec.firstPkt()) DebugRecError("Debug rec overflow!"); DebugRec.Clear(); #endif // return all control until this frame while (currChunk != chunks.end() && currChunk->Frame <= iFrame) { switch (currChunk->Type) { case RCT_Ctrl: pCtrl->Append(*currChunk->pCtrl); break; case RCT_CtrlPkt: { C4IDPacket Packet(*currChunk->pPkt); pCtrl->Add(Packet.getPktType(), static_cast<C4ControlPacket *>(Packet.getPkt())); Packet.Default(); break; } case RCT_End: // end of playback; stop it! Finished = true; break; #ifdef DEBUGREC default: // expect it to be debug rec // append to debug rec buffer if (currChunk->pDbg) { DebugRec.Add(CID_DebugRec, currChunk->pDbg); // the debugrec buffer is now responsible for deleting the packet currChunk->pDbg = NULL; } break; #endif } // next chunk NextChunk(); } // Debug log #ifdef DEBUGREC // sprintf(OSTR, "-- Frame %d:", Game.FrameCounter); Log(OSTR); // char Indent[256+1]; strcpy(Indent, ""); // pCtrl->deb_print(Indent); #endif return TRUE; }
char ResourceReader::CharNext() { if(m_bytesLeftInBuffer <= 0) { NextChunk(); } if(m_bytesLeftInBuffer) { --m_bytesLeftInBuffer; return m_buffer[m_bufferIndex++]; } else { return m_buffer[m_bufferIndex]; } }
HRESULT NextChunk(char *cmd, char **nextc) { char *tmp; tmp = strchr(cmd, 0x20); if (tmp == NULL) return E_FAIL; *tmp = 0; *nextc = tmp+1; if (**nextc == 0x3a){ NextChunk(*nextc, nextc); } return S_OK; }
MainObject::MainObject(QObject *parent) :QObject(parent) { file_fd=-1; payload_length=0; chunk_length=0; QString filename; char buffer[1024]; // // Read Command Options // RDCmdSwitch *cmd= new RDCmdSwitch(qApp->argc(),qApp->argv(),"wav_chunk_test", WAV_CHUNK_TEST_USAGE); for(unsigned i=0;i<cmd->keys();i++) { if(cmd->key(i)=="--filename") { filename=cmd->value(i); cmd->setProcessed(i,true); } if(!cmd->processed(i)) { fprintf(stderr,"wav_chunk_test: invalid option\n"); exit(256); } } if(filename.isEmpty()) { fprintf(stderr,"wav_chunk_test: missing filename\n"); exit(256); } // // Open File // if((file_fd=open(filename,O_RDONLY))<0) { fprintf(stderr,"wav_chunk_test: unable to open file [%s]\n", strerror(errno)); exit(256); } // // Get File Stats // struct stat stat; memset(&stat,0,sizeof(stat)); if(fstat(file_fd,&stat)!=0) { fprintf(stderr,"wav_chunk_test: unable to stat file [%s]\n", strerror(errno)); exit(256); } file_length=stat.st_size; // // Read Header // memset(buffer,0,1024); if(read(file_fd,buffer,4)!=4) { fprintf(stderr,"wav_chunk_test: file truncated\n"); exit(256); } if(strncmp(buffer,"RIFF",4)!=0) { fprintf(stderr,"wav_chunk_test: not a RIFF file\n"); exit(256); } if(read(file_fd,buffer,4)!=4) { fprintf(stderr,"wav_chunk_test: file truncated\n"); exit(256); } payload_length=((((uint32_t)buffer[3])&0xFF)<<24)+ ((((uint32_t)buffer[2])&0xFF)<<16)+ ((((uint32_t)buffer[1])&0xFF)<<8)+ ((((uint32_t)buffer[0])&0xFF)<<0); if(read(file_fd,buffer,4)!=4) { fprintf(stderr,"wav_chunk_test: file truncated\n"); exit(256); } if(strncmp(buffer,"WAVE",4)!=0) { fprintf(stderr,"wav_chunk_test: not a WAVE file\n"); exit(256); } printf(" File Length: %u\n",file_length); printf(" Payload Length: %u\n",payload_length); if(file_length!=(payload_length+8)) { printf("WARNING: Payload and file sizes disagree!\n"); } // // Enumerate Chunks // QString name; uint32_t start_pos; while((start_pos=NextChunk(name,&chunk_length))>0) { printf("Chunk: %s Start: %u [0x%X] Length: %u [0x%X]\n",(const char *)name,start_pos,start_pos,chunk_length+8,chunk_length+8); lseek(file_fd,chunk_length,SEEK_CUR); } // // Clean Up // close(file_fd); exit(0); }
void C4Playback::Check(C4RecordChunkType eType, const uint8_t *pData, int iSize) { // only if enabled if (DoNoDebugRec > 0) return; if (Game.FrameCounter < DEBUGREC_START_FRAME) return; C4PktDebugRec PktInReplay; bool fHasPacketFromHead = false; #ifdef DEBUGREC_EXTFILE #ifdef DEBUGREC_EXTFILE_WRITE // writing of external debugrec file DbgRecFile.Write(&eType, sizeof eType); int32_t iSize32 = iSize; DbgRecFile.Write(&iSize32, sizeof iSize32); DbgRecFile.Write(pData, iSize); return; #else int32_t iSize32 = 0; C4RecordChunkType eTypeRec = RCT_Undefined; DbgRecFile.Read(&eTypeRec, sizeof eTypeRec); DbgRecFile.Read(&iSize32, sizeof iSize32); if (iSize32) { StdBuf buf; buf.SetSize(iSize32); DbgRecFile.Read(buf.getMData(), iSize32); PktInReplay = C4PktDebugRec(eTypeRec, buf); } #endif #else // check debug rec in list C4IDPacket *pkt; if (pkt = DebugRec.firstPkt()) { // copy from list PktInReplay = *static_cast<C4PktDebugRec *>(pkt->getPkt()); DebugRec.Delete(pkt); } else { // special sync check skip... while (currChunk != chunks.end() && currChunk->Type == RCT_CtrlPkt) { C4IDPacket Packet(*currChunk->pPkt); C4ControlPacket *pCtrlPck = static_cast<C4ControlPacket *>(Packet.getPkt()); assert(!pCtrlPck->Sync()); Game.Control.ExecControlPacket(Packet.getPktType(), pCtrlPck); NextChunk(); } // record end? if (currChunk == chunks.end() || currChunk->Type == RCT_End || Finished) { Log("DebugRec end: All in sync!"); ++DoNoDebugRec; return; } // unpack directly from head if (currChunk->Type != eType) { DebugRecError(FormatString("Playback type %x, this type %x", currChunk->Type, eType).getData()); return; } PktInReplay = *currChunk->pDbg; fHasPacketFromHead = true; } #endif // DEBUGREC_EXTFILE // record end? if (PktInReplay.getType() == RCT_End) { Log("DebugRec end: All in sync (2)!"); ++DoNoDebugRec; return; } // replay packet is unpacked to PktInReplay now; check it if (PktInReplay.getType() != eType) { DebugRecError(FormatString("Type %s != %s", GetRecordChunkTypeName(PktInReplay.getType()), GetRecordChunkTypeName(eType)).getData()); return; } if (PktInReplay.getSize() != iSize) { DebugRecError(FormatString("Size %d != %d", (int)PktInReplay.getSize(), (int)iSize).getData()); } // check packet data if (memcmp(PktInReplay.getData(), pData, iSize)) { StdStrBuf sErr; sErr.Format("DbgRecPkt Type %s, size %d", GetRecordChunkTypeName(eType), iSize); sErr.Append(" Replay: "); StdBuf replay(PktInReplay.getData(), PktInReplay.getSize()); sErr.Append(GetDbgRecPktData(eType, replay)); sErr.Append(" Here: "); StdBuf here(pData, iSize); sErr.Append(GetDbgRecPktData(eType, here)); DebugRecError(sErr.getData()); } // packet is fine, jump over it if (fHasPacketFromHead) NextChunk(); }
loaded_sound LoadWave(char *FilePath) { loaded_sound Result = {}; //NOTE this is the loading the wave file code. Maybe all this should be pulled into the game layer read_file_result WaveResult = PlatformReadFile(FilePath); wave_header *WaveHeader = (wave_header *)WaveResult.Contents; Assert(WaveHeader->RiffID == WAVE_ChunkID_RIFF); Assert(WaveHeader->WaveID == WAVE_ChunkID_WAVE); uint32 ChannelCount = 0; uint32 SampleDataSize = 0; int16 *SampleData = 0; for (riff_iterator Iter = ParseChunkAt(WaveHeader + 1, (uint8 *)(WaveHeader + 1) + WaveHeader->Size - 4); IsValid(Iter); Iter = NextChunk(Iter)) { switch (GetType(Iter)) { case WAVE_ChunkID_fmt: { wave_fmt *fmt = (wave_fmt *)GetChunkData(Iter); // NOTE Assert that this file is in a supported format // Using PCM format; Assert(fmt->Format == 1); Assert(fmt->NumSamplesPerSecond == 48000); Assert(fmt->BitsPerSample == 16); Assert(fmt->BlockAlign == (sizeof(int16) * fmt->NumberOfChannels)); ChannelCount = fmt->NumberOfChannels; } break; case WAVE_ChunkID_data: { SampleData = (int16 *)GetChunkData(Iter); SampleDataSize = GetChunkDataSize(Iter); } break; } } Result.ChannelCount = ChannelCount; Result.SampleCount = SampleDataSize / (ChannelCount * sizeof(int16)); if (ChannelCount == 1) { Result.Samples[0] = SampleData; Result.Samples[1] = 0; } else if (ChannelCount == 2) { Result.Samples[0] = SampleData; Result.Samples[1] = SampleData + Result.SampleCount; for (uint32 SampleIndex = 0; SampleIndex < Result.SampleCount; ++SampleIndex) { int16 Source = SampleData[2 * SampleIndex]; SampleData[2 * SampleIndex] = SampleData[SampleIndex]; SampleData[SampleIndex] = Source; } } else { Assert(!"Invalid Channel Count"); } // TODO this only loads the left channel. MAYBE load the right channel too Result.ChannelCount = 1; return (Result); }