// File: OpenFodder[P]SOS_Unpacker/capsimg/Codec/CTRawCodecDecompressor.cpp
// Function: CCTRawCodec::DecompressTrackData(CapsWH*)
void CCTRawCodec::DecompressTrackData(PCAPSWH w)
{
	// source stream
	PUBYTE src = w->ctmem;

	// destination buffer
	PUBYTE dst = w->trkbuf[w->txact];

	// end of destination buffer
	PUBYTE max = dst + w->trklen[w->txact];

	// first, stored track
	PUBYTE mem = w->txsrc;

	// decode the data, see compressor for encoding
	while (dst < max) {
		UDWORD size = *src++;

		if (size & 0x80) {
			// copy block
			// 3 bit shift
			int shift = size >> 4 & 7;

			// 12 bit size
			size = ((size & 0xf) << 8) | (*src++);

			// 16 bit offset
			UDWORD ofs = *src++;
			ofs = (ofs << 8) | (*src++);
			PUBYTE buf = mem + ofs;

			if (shift) {
				// bitshift copy
				ofs = *buf++;
				while (size--) {
					ofs = (ofs << 8) | (*buf++);
					*dst++ = (UBYTE)(ofs >> shift);
				}
			} else {
				// simple copy
				while (size--)
					*dst++ = *buf++;
			}
		} else {
			// data block, 15 bit size
			size = (size << 8) | (*src++);
			while (size--)
				*dst++ = *src++;
		}
	}

	// update the source stream position
	w->ctmem = src;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rcx
movslq 0xa4(%rcx), %rcx
movq 0x40(%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq -0x8(%rbp), %rcx
movq -0x8(%rbp), %rdx
movslq 0xa4(%rdx), %rdx
movslq 0x68(%rcx,%rdx,4), %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x6b56
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl (%rax), %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x6afe
movl -0x2c(%rbp), %eax
shrl $0x4, %eax
andl $0x7, %eax
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %eax
andl $0xf, %eax
shll $0x8, %eax
movq -0x10(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x10(%rbp)
movzbl (%rcx), %ecx
orl %ecx, %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl (%rax), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
shll $0x8, %eax
movq -0x10(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x10(%rbp)
movzbl (%rcx), %ecx
orl %ecx, %eax
movl %eax, -0x34(%rbp)
movq -0x28(%rbp), %rax
movl -0x34(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x6ac4
movq -0x40(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x40(%rbp)
movzbl (%rax), %eax
movl %eax, -0x34(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x2c(%rbp)
cmpl $0x0, %eax
je 0x6ac2
movl -0x34(%rbp), %eax
shll $0x8, %eax
movq -0x40(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x40(%rbp)
movzbl (%rcx), %ecx
orl %ecx, %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl -0x30(%rbp), %ecx
shrl %cl, %eax
movb %al, %cl
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movb %cl, (%rax)
jmp 0x6a78
jmp 0x6afc
jmp 0x6ac6
movl -0x2c(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x2c(%rbp)
cmpl $0x0, %eax
je 0x6afa
movq -0x40(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x40(%rbp)
movb (%rax), %cl
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movb %cl, (%rax)
jmp 0x6ac6
jmp 0x6afc
jmp 0x6b51
movl -0x2c(%rbp), %eax
shll $0x8, %eax
movq -0x10(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x10(%rbp)
movzbl (%rcx), %ecx
orl %ecx, %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x2c(%rbp)
cmpl $0x0, %eax
je 0x6b4f
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movb (%rax), %cl
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movb %cl, (%rax)
jmp 0x6b1b
jmp 0x6b51
jmp 0x69bd
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x90(%rax)
popq %rbp
retq
nopw (%rax,%rax)