uint32_t Lz4StreamReader::ReadNextBlock(void) { // No more data if(m_lz4remain == 0) return 0; // Get the amount of compressed data in the next block uint32_t compressed; m_lz4pos = ReadLE32(m_lz4pos, &m_lz4remain, &compressed); // Read the next block of data from the compression stream int uncompressed = LZ4_decompress_safe(reinterpret_cast<const char*>(m_lz4pos), reinterpret_cast<char*>(m_block), compressed, LEGACY_BLOCKSIZE); if(uncompressed < 0) throw Exception(E_DECOMPRESS_CORRUPT, COMPRESSION_METHOD); // Advance the stream pointers to the next block of data m_lz4pos += compressed; m_lz4remain -= compressed; // Detect the end of the input stream by have less than a full block of data returned if(uncompressed < LEGACY_BLOCKSIZE) { m_lz4pos += m_lz4remain; m_lz4remain = 0; } // Reset the block current pointer and the number of remaining bytes m_blockcurrent = m_block; m_blockremain = static_cast<uint32_t>(uncompressed); return uncompressed; }
Lz4StreamReader::Lz4StreamReader(const void* base, size_t length) { if(!base) throw Exception(E_POINTER); if(length == 0) throw Exception(E_INVALIDARG); #ifdef _WIN64 if(length > UINT32_MAX) throw Exception(E_INVALIDARG); #endif intptr_t baseptr = intptr_t(base); // Read and validate the magic number from the start of the stream uint32_t magic; baseptr = ReadLE32(baseptr, &length, &magic); if(magic != LEGACY_MAGICNUMBER) throw Exception(E_DECOMPRESS_BADMAGIC, COMPRESSION_METHOD); // Allocate the decompression buffer m_block = new uint8_t[LEGACY_BLOCKSIZE]; if(!m_block) throw Exception(E_OUTOFMEMORY); // Initialize the decompression block member variables m_blockcurrent = m_block; m_blockremain = 0; // Initialize the LZ4 input stream member variables m_lz4pos = baseptr; m_lz4remain = length; }
void AGG::Cache::LoadOrgICN(Sprite & sp, const ICN::icn_t icn, const u16 index, bool reflect) { std::vector<u8> body; if(ReadChunk(ICN::GetString(icn), body)) { // loading original DEBUG(DBG_ENGINE, DBG_TRACE, "AGG::Cache::LoadOrgICN: " << ICN::GetString(icn) << ", " << index); const u16 count = ReadLE16(&body[0]); ICN::Header header1, header2; header1.Load(&body[6 + index * ICN::Header::SizeOf()]); if(index + 1 != count) header2.Load(&body[6 + (index + 1) * ICN::Header::SizeOf()]); const u32 size_data = (index + 1 != count ? header2.OffsetData() - header1.OffsetData() : // total size ReadLE32(&body[2]) - header1.OffsetData()); sp.Set(header1.Width(), header1.Height(), ICN::RequiresAlpha(icn)); sp.SetOffset(header1.OffsetX(), header1.OffsetY()); sp.SetColorKey(); Sprite::DrawICN(sp, &body[6 + header1.OffsetData()], size_data, reflect); Sprite::AddonExtensionModify(sp, icn, index); } else Error::Except("AGG::Cache::LoadOrgICN: ReadChunk: ", ICN::GetString(icn)); }
static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { MemBuffer* const mem = &dmux->mem_; uint32_t vp8x_size; if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; dmux->is_ext_format_ = 1; Skip(mem, TAG_SIZE); // VP8X vp8x_size = ReadLE32(mem); if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR; vp8x_size += vp8x_size & 1; if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR; if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA; dmux->feature_flags_ = ReadByte(mem); Skip(mem, 3); // Reserved. dmux->canvas_width_ = 1 + ReadLE24s(mem); dmux->canvas_height_ = 1 + ReadLE24s(mem); if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) { return PARSE_ERROR; // image final dimension is too large } Skip(mem, vp8x_size - VP8X_CHUNK_SIZE); // skip any trailing data. dmux->state_ = WEBP_DEMUX_PARSED_HEADER; if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR; if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; return ParseVP8XChunks(dmux); }
void ICN::Header::Load(const u8* p) { offset_x = ReadLE16(&p[0]); offset_y = ReadLE16(&p[2]); width = ReadLE16(&p[4]); height= ReadLE16(&p[6]); type = p[8]; offset_data = ReadLE32(&p[9]); }
__m256i inline Read8(const unsigned char* chunk, int offset) { __m256i ret = _mm256_set_epi32( ReadLE32(chunk + 0 + offset), ReadLE32(chunk + 64 + offset), ReadLE32(chunk + 128 + offset), ReadLE32(chunk + 192 + offset), ReadLE32(chunk + 256 + offset), ReadLE32(chunk + 320 + offset), ReadLE32(chunk + 384 + offset), ReadLE32(chunk + 448 + offset) ); return _mm256_shuffle_epi8(ret, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL)); }
bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) { opcodeRet = OP_INVALIDOPCODE; if (pvchRet) pvchRet->clear(); if (pc >= end) return false; // Read instruction if (end - pc < 1) return false; unsigned int opcode = *pc++; // Immediate operand if (opcode <= OP_PUSHDATA4) { unsigned int nSize = 0; if (opcode < OP_PUSHDATA1) { nSize = opcode; } else if (opcode == OP_PUSHDATA1) { if (end - pc < 1) return false; nSize = *pc++; } else if (opcode == OP_PUSHDATA2) { if (end - pc < 2) return false; nSize = ReadLE16(&pc[0]); pc += 2; } else if (opcode == OP_PUSHDATA4) { if (end - pc < 4) return false; nSize = ReadLE32(&pc[0]); pc += 4; } if (end - pc < 0 || (unsigned int)(end - pc) < nSize) return false; if (pvchRet) pvchRet->assign(pc, pc + nSize); pc += nSize; } opcodeRet = static_cast<opcodetype>(opcode); return true; }
plString hsStream::ReadSafeStringLong_TEMP() { plStringBuffer<char> name; uint32_t numChars = ReadLE32(); if (numChars > 0 && numChars <= GetSizeLeft()) { char *buff = name.CreateWritableBuffer(numChars); Read(numChars, buff); buff[numChars] = 0; // if the high bit is set, flip the bits. Otherwise it's a normal string, do nothing. if (buff[0] & 0x80) { for (int i = 0; i < numChars; i++) buff[i] = ~buff[i]; } } return name; }
plString hsStream::ReadSafeWStringLong_TEMP() { plStringBuffer<uint16_t> retVal; uint32_t numChars = ReadLE32(); if (numChars > 0 && numChars <= (GetSizeLeft()/2)) // divide by two because each char is two bytes { uint16_t *buff = retVal.CreateWritableBuffer(numChars); for (int i=0; i<numChars; i++) buff[i] = ReadLE16(); ReadLE16(); // we wrote the null out, read it back in buff[numChars] = 0; // But terminate it safely anyway if (buff[0]* 0x80) { for (int i=0; i<numChars; i++) buff[i] = ~buff[i]; } } return plString::FromUtf16(retVal); }
static int ReadHeader(MemBuffer* const mem) { const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE; uint32_t riff_size; // Basic file level validation. if (MemDataSize(mem) < min_size) return 0; if (memcmp(GetBuffer(mem), "RIFF", CHUNK_SIZE_BYTES) || memcmp(GetBuffer(mem) + CHUNK_HEADER_SIZE, "WEBP", CHUNK_SIZE_BYTES)) { return 0; } riff_size = ReadLE32(GetBuffer(mem) + TAG_SIZE); if (riff_size < CHUNK_HEADER_SIZE) return 0; if (riff_size > MAX_CHUNK_PAYLOAD) return 0; // There's no point in reading past the end of the RIFF chunk mem->riff_end_ = riff_size + CHUNK_HEADER_SIZE; if (mem->buf_size_ > mem->riff_end_) { mem->buf_size_ = mem->end_ = mem->riff_end_; } Skip(mem, RIFF_HEADER_SIZE); return 1; }
EventDate::EventDate(const void *ptr) { const u8 *ptr8 = static_cast<const u8 *>(ptr); u16 byte16 = 0; u32 byte32 = 0; // id if(0x00 != *ptr8) { DEBUG(DBG_GAME , DBG_WARN, "unknown id"); return; } ++ptr8; // resource byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.wood = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.mercury = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.ore = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.sulfur = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.crystal = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.gems = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.gold = byte32; // skip artifact byte16 = ReadLE16(ptr8); ++ptr8; ++ptr8; // allow computer byte16 = ReadLE16(ptr8); ++ptr8; ++ptr8; computer = byte16; // day of first occurent byte16 = ReadLE16(ptr8); ++ptr8; ++ptr8; first = byte16; // subsequent occurrences byte16 = ReadLE16(ptr8); ++ptr8; ++ptr8; subsequent = byte16; ptr8 += 6; colors = 0; // blue if(*ptr8) colors |= Color::BLUE; ++ptr8; // green if(*ptr8) colors |= Color::GREEN; ++ptr8; // red if(*ptr8) colors |= Color::RED; ++ptr8; // yellow if(*ptr8) colors |= Color::YELLOW; ++ptr8; // orange if(*ptr8) colors |= Color::ORANGE; ++ptr8; // purple if(*ptr8) colors |= Color::PURPLE; ++ptr8; // message message = Game::GetEncodeString(reinterpret_cast<const char *>(ptr8)); //if(SIZEMESSAGE < message.size()) DEBUG(DBG_GAME , DBG_WARN, "long message, incorrect block?"); DEBUG(DBG_GAME, DBG_INFO, "add: " << message); }
static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { MemBuffer* const mem = &dmux->mem_; int anim_chunks = 0; uint32_t vp8x_size; ParseStatus status = PARSE_OK; if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; dmux->is_ext_format_ = 1; Skip(mem, TAG_SIZE); // VP8X vp8x_size = ReadLE32(mem); if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR; vp8x_size += vp8x_size & 1; if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR; if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA; dmux->feature_flags_ = ReadByte(mem); Skip(mem, 3); // Reserved. dmux->canvas_width_ = 1 + ReadLE24s(mem); dmux->canvas_height_ = 1 + ReadLE24s(mem); if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) { return PARSE_ERROR; // image final dimension is too large } Skip(mem, vp8x_size - VP8X_CHUNK_SIZE); // skip any trailing data. dmux->state_ = WEBP_DEMUX_PARSED_HEADER; if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR; if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; do { int store_chunk = 1; const size_t chunk_start_offset = mem->start_; const uint32_t fourcc = ReadLE32(mem); const uint32_t chunk_size = ReadLE32(mem); const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1); if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR; switch (fourcc) { case MKFOURCC('V', 'P', '8', 'X'): { return PARSE_ERROR; } case MKFOURCC('A', 'L', 'P', 'H'): case MKFOURCC('V', 'P', '8', ' '): case MKFOURCC('V', 'P', '8', 'L'): { // check that this isn't an animation (all frames should be in an ANMF). if (anim_chunks > 0) return PARSE_ERROR; Rewind(mem, CHUNK_HEADER_SIZE); status = ParseSingleImage(dmux); break; } case MKFOURCC('A', 'N', 'I', 'M'): { if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR; if (MemDataSize(mem) < chunk_size_padded) { status = PARSE_NEED_MORE_DATA; } else if (anim_chunks == 0) { ++anim_chunks; dmux->bgcolor_ = ReadLE32(mem); dmux->loop_count_ = ReadLE16s(mem); Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE); } else { store_chunk = 0; goto Skip; } break; } case MKFOURCC('A', 'N', 'M', 'F'): { if (anim_chunks == 0) return PARSE_ERROR; // 'ANIM' precedes frames. status = ParseAnimationFrame(dmux, chunk_size_padded); break; } #ifdef WEBP_EXPERIMENTAL_FEATURES case MKFOURCC('F', 'R', 'G', 'M'): { status = ParseFragment(dmux, chunk_size_padded); break; } #endif case MKFOURCC('I', 'C', 'C', 'P'): { store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG); goto Skip; } case MKFOURCC('X', 'M', 'P', ' '): { store_chunk = !!(dmux->feature_flags_ & XMP_FLAG); goto Skip; } case MKFOURCC('E', 'X', 'I', 'F'): { store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG); goto Skip; } Skip: default: { if (chunk_size_padded <= MemDataSize(mem)) { if (store_chunk) { // Store only the chunk header and unpadded size as only the payload // will be returned to the user. if (!StoreChunk(dmux, chunk_start_offset, CHUNK_HEADER_SIZE + chunk_size)) { return PARSE_ERROR; } } Skip(mem, chunk_size_padded); } else { status = PARSE_NEED_MORE_DATA; } } } if (mem->start_ == mem->riff_end_) { break; } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { status = PARSE_NEED_MORE_DATA; } } while (status == PARSE_OK); return status; }
static WEBP_INLINE uint32_t GetLE32(MemBuffer* const mem) { const uint8_t* const data = mem->buf_ + mem->start_; const uint32_t val = ReadLE32(data); Skip(mem, 4); return val; }
static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); MemBuffer* const mem = &dmux->mem_; int anim_chunks = 0; ParseStatus status = PARSE_OK; do { int store_chunk = 1; const size_t chunk_start_offset = mem->start_; const uint32_t fourcc = ReadLE32(mem); const uint32_t chunk_size = ReadLE32(mem); const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1); if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR; switch (fourcc) { case MKFOURCC('V', 'P', '8', 'X'): { return PARSE_ERROR; } case MKFOURCC('A', 'L', 'P', 'H'): case MKFOURCC('V', 'P', '8', ' '): case MKFOURCC('V', 'P', '8', 'L'): { // check that this isn't an animation (all frames should be in an ANMF). if (anim_chunks > 0 || is_animation) return PARSE_ERROR; Rewind(mem, CHUNK_HEADER_SIZE); status = ParseSingleImage(dmux); break; } case MKFOURCC('A', 'N', 'I', 'M'): { if (chunk_size_padded < ANIM_CHUNK_SIZE) return PARSE_ERROR; if (MemDataSize(mem) < chunk_size_padded) { status = PARSE_NEED_MORE_DATA; } else if (anim_chunks == 0) { ++anim_chunks; dmux->bgcolor_ = ReadLE32(mem); dmux->loop_count_ = ReadLE16s(mem); Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE); } else { store_chunk = 0; goto Skip; } break; } case MKFOURCC('A', 'N', 'M', 'F'): { if (anim_chunks == 0) return PARSE_ERROR; // 'ANIM' precedes frames. status = ParseAnimationFrame(dmux, chunk_size_padded); break; } #ifdef WEBP_EXPERIMENTAL_FEATURES case MKFOURCC('F', 'R', 'G', 'M'): { status = ParseFragment(dmux, chunk_size_padded); break; } #endif case MKFOURCC('I', 'C', 'C', 'P'): { store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG); goto Skip; } case MKFOURCC('E', 'X', 'I', 'F'): { store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG); goto Skip; } case MKFOURCC('X', 'M', 'P', ' '): { store_chunk = !!(dmux->feature_flags_ & XMP_FLAG); goto Skip; } Skip: default: { if (chunk_size_padded <= MemDataSize(mem)) { if (store_chunk) { // Store only the chunk header and unpadded size as only the payload // will be returned to the user. if (!StoreChunk(dmux, chunk_start_offset, CHUNK_HEADER_SIZE + chunk_size)) { return PARSE_ERROR; } } Skip(mem, chunk_size_padded); } else { status = PARSE_NEED_MORE_DATA; } } } if (mem->start_ == mem->riff_end_) { break; } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { status = PARSE_NEED_MORE_DATA; } } while (status == PARSE_OK); return status; }
// Store image bearing chunks to 'frame'. static ParseStatus StoreFrame(int frame_num, uint32_t min_size, MemBuffer* const mem, Frame* const frame) { int alpha_chunks = 0; int image_chunks = 0; int done = (MemDataSize(mem) < min_size); ParseStatus status = PARSE_OK; if (done) return PARSE_NEED_MORE_DATA; do { const size_t chunk_start_offset = mem->start_; const uint32_t fourcc = ReadLE32(mem); const uint32_t payload_size = ReadLE32(mem); const uint32_t payload_size_padded = payload_size + (payload_size & 1); const size_t payload_available = (payload_size_padded > MemDataSize(mem)) ? MemDataSize(mem) : payload_size_padded; const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available; if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR; if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA; switch (fourcc) { case MKFOURCC('A', 'L', 'P', 'H'): if (alpha_chunks == 0) { ++alpha_chunks; frame->img_components_[1].offset_ = chunk_start_offset; frame->img_components_[1].size_ = chunk_size; frame->has_alpha_ = 1; frame->frame_num_ = frame_num; Skip(mem, payload_available); } else { goto Done; } break; case MKFOURCC('V', 'P', '8', 'L'): if (alpha_chunks > 0) return PARSE_ERROR; // VP8L has its own alpha // fall through case MKFOURCC('V', 'P', '8', ' '): if (image_chunks == 0) { // Extract the bitstream features, tolerating failures when the data // is incomplete. WebPBitstreamFeatures features; const VP8StatusCode vp8_status = WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size, &features); if (status == PARSE_NEED_MORE_DATA && vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) { return PARSE_NEED_MORE_DATA; } else if (vp8_status != VP8_STATUS_OK) { // We have enough data, and yet WebPGetFeatures() failed. return PARSE_ERROR; } ++image_chunks; frame->img_components_[0].offset_ = chunk_start_offset; frame->img_components_[0].size_ = chunk_size; frame->width_ = features.width; frame->height_ = features.height; frame->has_alpha_ |= features.has_alpha; frame->frame_num_ = frame_num; frame->complete_ = (status == PARSE_OK); Skip(mem, payload_available); } else { goto Done; } break; Done: default: // Restore fourcc/size when moving up one level in parsing. Rewind(mem, CHUNK_HEADER_SIZE); done = 1; break; } if (mem->start_ == mem->riff_end_) { done = 1; } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { status = PARSE_NEED_MORE_DATA; } } while (!done && status == PARSE_OK); return status; }
static void UpdateVGM(VGM_PBK* vgmPlay, UINT16 Samples) { const dword/*32*/ vgmLen = vgmPlay->file->dataLen; const UINT8* vgmData = vgmPlay->file->data; const UINT8* VGMPnt; dword/*32*/ VGMPos; dword/*32*/ VGMSmplPos; UINT8 Command; UINT8 blockType; dword/*32*/ blockLen; vgmPlay->pbSmplPos += Samples; VGMPos = vgmPlay->vgmPos; VGMSmplPos = vgmPlay->vgmSmplPos; while(VGMSmplPos < vgmPlay->pbSmplPos && ! vgmPlay->vgmEnd) { VGMPnt = &vgmData[VGMPos]; Command = VGMPnt[0x00]; switch(Command & 0xF0) { case 0x70: // small delay (1-16 samples) VGMSmplPos += (Command & 0x0F) + 0x01; VGMPos += 0x01; break; case 0x80: // DAC write + small delay (0-15 samples) VGMSmplPos += (Command & 0x0F); VGMPos += 0x01; break; case 0x60: switch(Command) { case 0x66: // End Of File vgmPlay->vgmPos = VGMPos; vgmPlay->vgmSmplPos = VGMSmplPos; if (! DoVgmLoop(vgmPlay)) vgmPlay->vgmEnd = 0x01; VGMPos = vgmPlay->vgmPos; VGMSmplPos = vgmPlay->vgmSmplPos; break; case 0x62: // 1/60s delay VGMSmplPos += 735; VGMPos += 0x01; break; case 0x63: // 1/50s delay VGMSmplPos += 882; VGMPos += 0x01; break; case 0x61: // xx Sample Delay VGMSmplPos += ReadLE16(&VGMPnt[0x01]); VGMPos += 0x03; break; case 0x67: // Data Block (PCM Data Stream) blockType = VGMPnt[0x02]; blockLen = ReadLE32(&VGMPnt[0x03]); blockLen &= 0x7FFFFFFF; VGMPos += 0x07 + blockLen; break; case 0x68: // PCM RAM write VGMPos += 0x0C; break; default: vgmPlay->vgmEnd = 0x01; break; } break; case 0x50: if (Command == 0x50) { VGMPos += 0x02; // SN76496 write break; } switch(Command) { case 0x51: // YM2413 write ym2413_write(vgmPlay, VGMPnt[0x01], VGMPnt[0x02]); break; case 0x5A: // YM3812 write ym3812_write(vgmPlay, VGMPnt[0x01], VGMPnt[0x02]); break; case 0x5B: // YM3526 write case 0x5C: // Y8950 write ym3512_write(vgmPlay, VGMPnt[0x01], VGMPnt[0x02]); break; case 0x5E: // YMF262 write, port 0 case 0x5F: // YMF262 write, port 1 ymf262_write(vgmPlay, Command & 0x01, VGMPnt[0x01], VGMPnt[0x02]); break; } VGMPos += 0x03; break; case 0x30: VGMPos += 0x02; break; case 0x40: case 0xA0: case 0xB0: VGMPos += 0x03; break; case 0xC0: case 0xD0: VGMPos += 0x04; break; case 0xE0: case 0xF0: VGMPos += 0x05; break; case 0x90: switch(Command) { case 0x90: // DAC Ctrl: Setup Chip VGMPos += 0x05; break; case 0x91: // DAC Ctrl: Set Data VGMPos += 0x05; break; case 0x92: // DAC Ctrl: Set Freq VGMPos += 0x06; break; case 0x93: // DAC Ctrl: Play from Start Pos VGMPos += 0x0B; break; case 0x94: // DAC Ctrl: Stop immediately VGMPos += 0x02; break; case 0x95: // DAC Ctrl: Play Block (small) VGMPos += 0x05; break; default: vgmPlay->vgmEnd = 0x01; break; } break; default: vgmPlay->vgmEnd = 0x01; return; } if (VGMPos >= vgmLen) vgmPlay->vgmEnd = 0x01; } vgmPlay->vgmPos = VGMPos; vgmPlay->vgmSmplPos = VGMSmplPos; if (vgmPlay->vgmEnd) StopPlayback(vgmPlay); return; }
EventMaps::EventMaps(s32 index, const void *ptr) { SetIndex(index); const u8 *ptr8 = static_cast<const u8 *>(ptr); u16 byte16 = 0; u32 byte32 = 0; // id if(0x01 != *ptr8) { DEBUG(DBG_GAME, DBG_WARN, "unknown id"); return; } ++ptr8; // resource byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.wood = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.mercury = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.ore = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.sulfur = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.crystal = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.gems = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.gold = byte32; // artifact byte16 = ReadLE16(ptr8); ++ptr8; ++ptr8; artifact = byte16; // allow computer computer = *ptr8; ++ptr8; // cancel event after first visit cancel = *ptr8; ptr8 += 11; colors = 0; // blue if(*ptr8) colors |= Color::BLUE; ++ptr8; // green if(*ptr8) colors |= Color::GREEN; ++ptr8; // red if(*ptr8) colors |= Color::RED; ++ptr8; // yellow if(*ptr8) colors |= Color::YELLOW; ++ptr8; // orange if(*ptr8) colors |= Color::ORANGE; ++ptr8; // purple if(*ptr8) colors |= Color::PURPLE; ++ptr8; // message message = Game::GetEncodeString(reinterpret_cast<const char *>(ptr8)); DEBUG(DBG_GAME , DBG_INFO, "add: " << message); }
Riddle::Riddle(s32 index, const void *ptr) : valid(false) { SetIndex(index); const u8 *ptr8 = static_cast<const u8 *>(ptr); u16 byte16 = 0; u32 byte32 = 0; // id if(0x00 != *ptr8) { DEBUG(DBG_GAME , DBG_WARN, "unknown id"); return; } ++ptr8; // resource byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.wood = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.mercury = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.ore = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.sulfur = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.crystal = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.gems = byte32; byte32 = ReadLE32(ptr8); ptr8 += 4;; resource.gold = byte32; // artifact byte16 = ReadLE16(ptr8); ++ptr8; ++ptr8; artifact = byte16; // count answers u8 count = *ptr8; ++ptr8; // answers for(u8 i = 0; i < 8; ++i) { std::string str = String::Lower(reinterpret_cast<const char *>(ptr8)); if(count-- && str.size()) { answers.push_back(Game::GetEncodeString(str.c_str())); answers.push_back(Game::GetEncodeString(reinterpret_cast<const char *>(ptr8))); }; ptr8 += 13; } // message message = Game::GetEncodeString(reinterpret_cast<const char *>(ptr8)); valid = true; DEBUG(DBG_GAME, DBG_INFO, "add: " << message); }