Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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));
}
Exemple #4
0
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);
}
Exemple #5
0
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));
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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);
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
// 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;
}
Exemple #16
0
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;
}
Exemple #17
0
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);
}
Exemple #18
0
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);
}