// File: OpenFodder[P]SOS_Unpacker/capsimg/Codec/CTRawCodecDecompressor.cpp
// Function: CCTRawCodec::DecompressTrack(CapsWH*, unsigned char*, int, unsigned char*)
PCAPSWH CCTRawCodec::DecompressTrack(PCAPSWH w, PUBYTE src, int slen, PUBYTE dst)
{
	CapsPack cpk;

	// get track header
	PCAPSPACK pk = GetPackHeader(&cpk, src, slen);
	if (!pk)
		return NULL;

	// use caller supplied buffer or allocate a new one
	w->rawbuf = NULL;
	FreeUncompressedTrack(w);
	w->rawlen = pk->usize;
	w->rawbuf = dst;
	if (!w->rawbuf && w->rawlen)
		w->rawbuf = new UBYTE[w->rawlen];

	// read track number
	w->ctmem = src + sizeof(CapsPack);
	w->trkcnt = CTR(w, 1);

	// read <track number> track sizes and calculate track buffer positions
	dst = w->rawbuf;
	for (int trk = 0; trk < w->trkcnt; trk++) {
		w->trklen[trk] = CTR(w, 2);
		w->trkbuf[trk] = dst;
		dst += w->trklen[trk];
	}

	// first track is stored
	if (w->trkcnt) {
		w->txsrc = w->trkbuf[0];
		w->txlen = w->trklen[0];
		memmove(w->txsrc, w->ctmem, w->txlen);
		w->ctmem += w->txlen;
	}

	// other tracks are compressed as deltas against the stored track
	for (w->txact = 1; w->txact < w->trkcnt; w->txact++)
		DecompressTrackData(w);

	return w;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %edx
leaq -0x40(%rbp), %rdi
callq 0x5f80
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x673f
movq $0x0, -0x8(%rbp)
jmp 0x68f3
movq -0x10(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x10(%rbp), %rdi
callq 0x5cc0
movq -0x48(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x38(%rax)
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x30(%rax)
jne 0x679b
movq -0x10(%rbp), %rax
cmpl $0x0, 0x38(%rax)
je 0x679b
movq -0x10(%rbp), %rax
movslq 0x38(%rax), %rdi
callq 0x4040
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rcx
addq $0x18, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x6900
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x7c(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x7c(%rcx), %eax
jge 0x6836
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x6900
movl %eax, %edx
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl %edx, 0x68(%rax,%rcx,4)
movq -0x28(%rbp), %rdx
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movq %rdx, 0x40(%rax,%rcx,8)
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl 0x68(%rax,%rcx,4), %ecx
movq -0x28(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x67d8
movq -0x10(%rbp), %rax
cmpl $0x0, 0x7c(%rax)
je 0x68ac
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x98(%rax)
movq -0x10(%rbp), %rax
movl 0x68(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xa0(%rax)
movq -0x10(%rbp), %rax
movq 0x98(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rsi
movq -0x10(%rbp), %rax
movslq 0xa0(%rax), %rdx
callq 0x43d0
movq -0x10(%rbp), %rax
movl 0xa0(%rax), %edx
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rcx
movslq %edx, %rdx
addq %rdx, %rcx
movq %rcx, 0x90(%rax)
movq -0x10(%rbp), %rax
movl $0x1, 0xa4(%rax)
movq -0x10(%rbp), %rax
movl 0xa4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x7c(%rcx), %eax
jge 0x68eb
movq -0x10(%rbp), %rdi
callq 0x6960
movq -0x10(%rbp), %rax
movl 0xa4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xa4(%rax)
jmp 0x68ba
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)