// File: /workspace/github_c_makefile_star2_O1/jonof[P]jftekwar/jfbuild/src/mmulti.c
// Function: getpacket
int getpacket (int *retother, unsigned char *bufptr)
{
	int i, j, k, ic0, crc16ofs, messleng, other;
	static int warned = 0;

	if (numplayers < 2) return(0);

	if (netready)
	{
		for(i=connecthead;i>=0;i=connectpoint2[i])
		{
			if (i != myconnectindex) dosendpackets(i);
			if ((networkmode == MMULTI_MODE_MS) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
		}
	}

	tims = GetTickCount();

	while (netread(&other,pakbuf,sizeof(pakbuf)))
	{
			//Packet format:
			//   short crc16ofs;       //offset of crc16
			//   int icnt0;           //earliest unacked packet
			//   char ibits[32];       //ack status of packets icnt0<=i<icnt0+256
			//   while (short leng)    //leng: !=0 for packet, 0 for no more packets
			//   {
			//      int ocnt;         //index of following packet data
			//      char pak[leng];    //actual packet data :)
			//   }
			//   unsigned short crc16; //CRC16 of everything except crc16
		k = 0;
		crc16ofs = (int)(*(unsigned short *)&pakbuf[k]); k += 2;

		if (crc16ofs+2 > (int)sizeof(pakbuf)) {
#ifdef MMULTI_DEBUG_SENDRECV
			debugprintf("mmulti debug: wrong-sized packet from %d\n", other);
#endif
		} else if (getcrc16(pakbuf,crc16ofs) != (*(unsigned short *)&pakbuf[crc16ofs])) {
#ifdef MMULTI_DEBUG_SENDRECV
			debugprintf("mmulti debug: bad crc in packet from %d\n", other);
#endif
		} else {
			ic0 = *(int *)&pakbuf[k]; k += 4;
			if (ic0 == -1)
			{
				// Peers send each other 0xaa and respond with 0xab containing their opinion
				// of the requesting peer's placement within the order.

				// Slave sends 0xaa to Master at initmultiplayerscycle() and waits for 0xab response.
				// Master responds to slave with 0xab whenever it receives a 0xaa - even if during game!
				if (pakbuf[k] == 0xaa)
				{
					int sendother = -1;
#ifdef MMULTI_DEBUG_SENDRECV
					const char *addr = presentaddress((struct sockaddr *)&snatchhost);
#endif

					if (networkmode == MMULTI_MODE_MS) {
						// Master-slave.
						if (other == myconnectindex && myconnectindex == connecthead) {
							// This the master and someone new is calling. Find them a place.
#ifdef MMULTI_DEBUG_SENDRECV
							debugprintf("mmulti debug: got ping from new host %s\n", addr);
#endif
							for (other = 1; other < numplayers; other++) {
								if (otherhost[other].ss_family == PF_UNSPEC) {
									sendother = other;
#ifdef MMULTI_DEBUG_SENDRECV
									debugprintf("mmulti debug: giving %s player %d\n", addr, other);
#endif
									break;
								}
							}
						} else {
							// Repeat back to them their position.
#ifdef MMULTI_DEBUG_SENDRECV
							debugprintf("mmulti debug: got ping from player %d\n", other);
#endif
							sendother = other;
						}
					} else {
						// Peer-to-peer mode.
						if (other == myconnectindex) {
#ifdef MMULTI_DEBUG_SENDRECV
							debugprintf("mmulti debug: got ping from unknown host %s\n", addr);
#endif
						} else {
#ifdef MMULTI_DEBUG_SENDRECV
							debugprintf("mmulti debug: got ping from peer %d\n", other);
#endif
							sendother = other;
						}
					}

					if (sendother >= 0) {
						savesnatchhost(sendother);
						lastrecvtims[sendother] = tims;

							//   short crc16ofs;        //offset of crc16
							//   int icnt0;             //-1 (special packet for MMULTI.C's player collection)
							//   char type;				// 0xab
							//   char connectindex;
							//   char numplayers;
							//   char netready;
							//   unsigned short crc16;  //CRC16 of everything except crc16
						k = 2;
						*(int *)&pakbuf[k] = -1; k += 4;
						pakbuf[k++] = 0xab;
						pakbuf[k++] = (char)sendother;
						pakbuf[k++] = (char)numplayers;
						pakbuf[k++] = (char)netready;
						*(unsigned short *)&pakbuf[0] = (unsigned short)k;
						*(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2;
						netsend(sendother,pakbuf,k);
					}
				}
				else if (pakbuf[k] == 0xab)
				{
					if (networkmode == MMULTI_MODE_MS) {
						// Master-slave.
						if (((unsigned int)pakbuf[k+1] < (unsigned int)pakbuf[k+2]) &&
							 ((unsigned int)pakbuf[k+2] < (unsigned int)MAXPLAYERS) &&
							 other == connecthead)
						{
#ifdef MMULTI_DEBUG_SENDRECV
								debugprintf("mmulti debug: master gave us player %d in a %d player game\n",
									(int)pakbuf[k+1], (int)pakbuf[k+2]);
#endif

							if ((int)pakbuf[k+1] != myconnectindex ||
									(int)pakbuf[k+2] != numplayers)
							{
								myconnectindex = (int)pakbuf[k+1];
								numplayers = (int)pakbuf[k+2];

								connecthead = 0;
								for(i=0;i<numplayers-1;i++) connectpoint2[i] = i+1;
								connectpoint2[numplayers-1] = -1;
							}

							netready = netready || (int)pakbuf[k+3];

							savesnatchhost(connecthead);
							lastrecvtims[connecthead] = tims;
						}
					} else {
						// Peer-to-peer. Verify that our peer's understanding of the
						// order and player count matches with ours.
						if (myconnectindex != (int)pakbuf[k+1] ||
								numplayers != (int)pakbuf[k+2]) {
							if (!warned) {
								const char *addr = presentaddress((struct sockaddr *)&snatchhost);
								printf("mmulti error: host %s (peer %d) believes this machine is "
									"player %d in a %d-player game! The game will not start until "
									"every machine is in agreement.\n",
									addr, other, (int)pakbuf[k+1], (int)pakbuf[k+2]);
							}
							warned = 1;
						} else {
							savesnatchhost(other);
							lastrecvtims[other] = tims;
						}
					}
				}
			}
			else
			{
				if (other == myconnectindex) {
#ifdef MMULTI_DEBUG_SENDRECV
					debugprintf("mmulti debug: got a packet from unknown host %s\n",
								presentaddress((struct sockaddr *)&snatchhost));
					return 0;
#endif
				}
				if (ocnt0[other] < ic0) ocnt0[other] = ic0;
				for(i=ic0;i<min(ic0+256,ocnt1[other]);i++)
					if (pakbuf[((i-ic0)>>3)+k]&(1<<((i-ic0)&7)))
						opak[other][i&(FIFSIZ-1)] = 0;
				k += 32;

				messleng = (int)(*(unsigned short *)&pakbuf[k]); k += 2;
				while (messleng)
				{
					j = *(int *)&pakbuf[k]; k += 4;
					if ((j >= icnt0[other]) && (!ipak[other][j&(FIFSIZ-1)]))
					{
						if (pakmemi+messleng+2 > (int)sizeof(pakmem)) pakmemi = 1;
						ipak[other][j&(FIFSIZ-1)] = pakmemi;
						*(short *)&pakmem[pakmemi] = messleng;
						memcpy(&pakmem[pakmemi+2],&pakbuf[k],messleng); pakmemi += messleng+2;
					}
					k += messleng;
					messleng = (int)(*(unsigned short *)&pakbuf[k]); k += 2;
				}

				lastrecvtims[other] = tims;
			}
		}
	}

		//Return next valid packet from any player
	if (!bufptr) return(0);
	for(i=connecthead;i>=0;i=connectpoint2[i])
	{
		if (i != myconnectindex)
		{
			j = ipak[i][icnt0[i]&(FIFSIZ-1)];
			if (j)
			{
				messleng = *(short *)&pakmem[j]; memcpy(bufptr,&pakmem[j+2],messleng);
				*retother = i; ipak[i][icnt0[i]&(FIFSIZ-1)] = 0; icnt0[i]++;
				return(messleng);
			}
		}
		if ((networkmode == MMULTI_MODE_MS) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
	}

	return(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
xorl %r13d, %r13d
cmpl $0x2, 0x7476bd(%rip)    # 0x7a2b0c
jl 0x5ba4e
movq %rsi, 0x10(%rsp)
movq %rdi, 0x8(%rsp)
cmpl $0x0, 0x7476fa(%rip)    # 0x7a2b60
setne %al
movl 0x7476a1(%rip), %ebp    # 0x7a2b10
testl %ebp, %ebp
setns %cl
andb %al, %cl
leaq 0x7476a3(%rip), %rbx    # 0x7a2b20
cmpb $0x1, %cl
jne 0x5b4b1
cmpl 0x74767c(%rip), %ebp    # 0x7a2b04
je 0x5b491
movl %ebp, %edi
callq 0x5baef
cmpl $0x0, 0x853d0(%rip)     # 0xe0868
jne 0x5b4a8
movl 0x747664(%rip), %eax    # 0x7a2b04
cmpl 0x74766a(%rip), %eax    # 0x7a2b10
jne 0x5b4b1
movl %ebp, %eax
movl (%rbx,%rax,4), %ebp
testl %ebp, %ebp
jns 0x5b482
callq 0x5ba97
movl %eax, 0x7476a8(%rip)    # 0x7a2b64
leaq 0x74777d(%rip), %r12    # 0x7a2c40
leaq 0x4(%rsp), %rdi
movq %r12, %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x5a6bb
testl %eax, %eax
je 0x5b9d5
leaq 0x4(%rsp), %rbx
leaq 0xb57927(%rip), %r14    # 0xbb2e10
leaq 0x74f910(%rip), %r15    # 0x7aae00
movzwl 0x747749(%rip), %eax    # 0x7a2c40
cmpq $0xfe, %rax
ja 0x5b6a5
xorl %ecx, %ecx
testq %rax, %rax
je 0x5b52c
leaq 0x1(%rax), %rdx
movzbl %ch, %esi
shll $0x8, %ecx
movzwl %cx, %ecx
movzbl -0x2(%rdx,%r12), %edi
xorl %esi, %edi
xorl (%r14,%rdi,4), %ecx
decq %rdx
cmpq $0x1, %rdx
jg 0x5b50e
cmpw (%rax,%r12), %cx
jne 0x5b6a5
movl 0x747705(%rip), %eax    # 0x7a2c42
cmpl $-0x1, %eax
je 0x5b6c2
movslq 0x4(%rsp), %r13
leaq 0x74f82e(%rip), %rcx    # 0x7aad80
cmpl %eax, (%rcx,%r13,4)
jge 0x5b563
leaq 0x74f821(%rip), %rcx    # 0x7aad80
movl %eax, (%rcx,%r13,4)
leal 0x100(%rax), %ecx
leaq 0x74f850(%rip), %rdx    # 0x7aadc0
movl (%rdx,%r13,4), %edx
cmpl %edx, %ecx
cmovgel %edx, %ecx
cmpl %eax, %edx
jle 0x5b5bc
xorl %edx, %edx
movl %edx, %esi
sarl $0x3, %esi
movslq %esi, %rsi
movzbl 0x6(%rsi,%r12), %esi
movl %edx, %edi
andl $0x7, %edi
btl %edi, %esi
jae 0x5b5b1
leal (%rax,%rdx), %esi
andl $0x1ff, %esi            # imm = 0x1FF
movq %r13, %rdi
shlq $0xb, %rdi
addq %r15, %rdi
movl $0x0, (%rdi,%rsi,4)
leal (%rax,%rdx), %esi
incl %esi
incl %edx
cmpl %ecx, %esi
jl 0x5b57f
movzwl 0x7476a3(%rip), %ecx    # 0x7a2c66
testw %cx, %cx
leaq 0x7477b3(%rip), %rsi    # 0x7a2d80
je 0x5b681
movl 0x85297(%rip), %eax     # 0xe0870
leaq 0x747760(%rip), %rdx    # 0x7a2d40
movl (%rdx,%r13,4), %ebx
movl $0x28, %edx
movzwl %cx, %ebp
movslq %edx, %r14
movl (%r14,%r12), %ecx
addq $0x4, %r14
cmpl %ebx, %ecx
jl 0x5b66c
andl $0x1ff, %ecx            # imm = 0x1FF
movq %r13, %rdx
shlq $0xb, %rdx
addq %rsi, %rdx
cmpl $0x0, (%rdx,%rcx,4)
jne 0x5b66c
leal (%rax,%rbp), %esi
cmpl $0x3fffff, %esi         # imm = 0x3FFFFF
jl 0x5b62b
movl $0x1, 0x8524a(%rip)     # 0xe0870
movl $0x1, %eax
leaq (%rdx,%rcx,4), %rcx
movl %eax, (%rcx)
movslq %eax, %r15
leaq 0x7577c5(%rip), %rcx    # 0x7b2e00
movw %bp, (%r15,%rcx)
leal 0x2(%r15), %eax
movslq %eax, %rdi
addq %rcx, %rdi
movslq %r14d, %rsi
addq %r12, %rsi
movq %rbp, %rdx
callq 0x80e0
leal (%r15,%rbp), %eax
addl $0x2, %eax
movl %eax, 0x8520b(%rip)     # 0xe0870
leaq 0x747714(%rip), %rsi    # 0x7a2d80
addq %rbp, %r14
leal 0x2(%r14), %edx
movzwl (%r12,%r14), %ecx
testw %cx, %cx
jne 0x5b5e9
movl 0x7474dd(%rip), %eax    # 0x7a2b64
leaq 0x7474e2(%rip), %rcx    # 0x7a2b70
movl %eax, (%rcx,%r13,4)
leaq 0x4(%rsp), %rbx
leaq 0xb57772(%rip), %r14    # 0xbb2e10
leaq 0x74f75b(%rip), %r15    # 0x7aae00
movq %rbx, %rdi
movq %r12, %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x5a6bb
testl %eax, %eax
jne 0x5b4f0
jmp 0x5b9d5
movzbl 0x74757d(%rip), %eax    # 0x7a2c46
cmpl $0xab, %eax
je 0x5b6fd
cmpl $0xaa, %eax
jne 0x5b6a5
cmpl $0x0, 0x8518a(%rip)     # 0xe0868
movl 0x4(%rsp), %eax
movl 0x74741c(%rip), %ecx    # 0x7a2b04
je 0x5b7d6
cmpl %ecx, %eax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmovel %ecx, %eax
jmp 0x5b8f2
cmpl $0x0, 0x85164(%rip)     # 0xe0868
je 0x5b82c
movl 0x7473f4(%rip), %ecx    # 0x7a2b04
movzbl 0x747530(%rip), %eax    # 0x7a2c47
cmpl %eax, %ecx
jne 0x5b791
movzbl 0x747526(%rip), %eax    # 0x7a2c48
cmpl %eax, 0x7473e4(%rip)    # 0x7a2b0c
jne 0x5b791
movslq 0x4(%rsp), %rax
cmpl %eax, %ecx
je 0x5b77c
movq %rax, %rdi
shlq $0x7, %rdi
leaq 0x7469ef(%rip), %rcx    # 0x7a2130
addq %rcx, %rdi
movl $0x10, %ecx
leaq 0x747320(%rip), %rsi    # 0x7a2a70
rep  movsq (%rsi), %es:(%rdi)
movl 0x747397(%rip), %ecx    # 0x7a2af0
leaq 0x7471d0(%rip), %rdx    # 0x7a2930
movl %ecx, (%rdx,%rax,4)
movq %rax, %rcx
shlq $0x4, %rcx
movups 0x747383(%rip), %xmm0   # 0x7a2af4
leaq 0x7471f8(%rip), %rdx    # 0x7a2970
movups %xmm0, (%rcx,%rdx)
movl 0x7473e2(%rip), %ecx    # 0x7a2b64
leaq 0x7473e7(%rip), %rdx    # 0x7a2b70
movl %ecx, (%rdx,%rax,4)
jmp 0x5b6a5
cmpb $0x0, 0xb57668(%rip)    # 0xbb2e00
jne 0x5b7ca
leaq 0x7472cf(%rip), %rdi    # 0x7a2a70
callq 0x5b0ad
movl 0x4(%rsp), %edx
movzbl 0x747496(%rip), %ecx    # 0x7a2c47
movzbl 0x74748f(%rip), %r8d    # 0x7a2c48
leaq 0x482c3(%rip), %rdi     # 0xa3a83
movq %rax, %rsi
xorl %eax, %eax
callq 0x36050
movb $0x1, 0xb5762f(%rip)    # 0xbb2e00
jmp 0x5b6a5
cmpl %ecx, %eax
jne 0x5b8f2
cmpl 0x74732c(%rip), %ecx    # 0x7a2b10
jne 0x5b8f2
movl 0x74731c(%rip), %edx    # 0x7a2b0c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl $0x1, %ecx
cmpl $0x2, %edx
jl 0x5b8ee
movl $0x1, %ecx
leaq 0x7469a1(%rip), %rsi    # 0x7a21b0
cmpw $0x0, (%rsi)
je 0x5b8ec
incq %rcx
subq $-0x80, %rsi
cmpq %rcx, %rdx
jne 0x5b80f
movl %edx, %ecx
jmp 0x5b8ee
movzbl 0x747414(%rip), %ecx    # 0x7a2c47
movzbl 0x74740e(%rip), %eax    # 0x7a2c48
cmpb %al, %cl
setae %dl
cmpb $0x10, %al
setae %sil
orb %dl, %sil
jne 0x5b6a5
movl 0x4(%rsp), %edx
cmpl 0x7472b8(%rip), %edx    # 0x7a2b10
jne 0x5b6a5
cmpl %ecx, 0x7472a0(%rip)    # 0x7a2b04
jne 0x5b86e
cmpl %eax, 0x7472a0(%rip)    # 0x7a2b0c
je 0x5b8b5
movl %ecx, 0x747290(%rip)    # 0x7a2b04
movl %eax, 0x747292(%rip)    # 0x7a2b0c
movl $0x0, 0x74728c(%rip)    # 0x7a2b10
cmpb $0x2, %al
leaq 0x747293(%rip), %rdi    # 0x7a2b20
jb 0x5b8ad
leal -0x1(%rax), %ecx
movl %ecx, %ecx
shlq $0x2, %rcx
movl $0x1, %edx
xorl %esi, %esi
movl %edx, (%rsi,%rdi)
addq $0x4, %rsi
incl %edx
cmpq %rsi, %rcx
jne 0x5b89f
movl $0xffffffff, -0x4(%rdi,%rax,4) # imm = 0xFFFFFFFF
cmpl $0x0, 0x7472a4(%rip)    # 0x7a2b60
setne %al
cmpb $0x0, 0x747383(%rip)    # 0x7a2c49
setne %cl
orb %al, %cl
movzbl %cl, %eax
movl %eax, 0x74728c(%rip)    # 0x7a2b60
movslq 0x747235(%rip), %rax    # 0x7a2b10
cmpl %eax, 0x747223(%rip)    # 0x7a2b04
jne 0x5b733
jmp 0x5b77c
movl %ecx, %eax
movl %ecx, 0x4(%rsp)
testl %eax, %eax
js 0x5b6a5
movl %eax, %edx
cmpl %eax, 0x747202(%rip)    # 0x7a2b04
je 0x5b94d
movq %rdx, %rdi
shlq $0x7, %rdi
leaq 0x74681e(%rip), %rcx    # 0x7a2130
addq %rcx, %rdi
movl $0x10, %ecx
leaq 0x74714f(%rip), %rsi    # 0x7a2a70
rep  movsq (%rsi), %es:(%rdi)
movl 0x7471c6(%rip), %ecx    # 0x7a2af0
leaq 0x746fff(%rip), %rsi    # 0x7a2930
movl %ecx, (%rsi,%rdx,4)
movq %rdx, %rcx
shlq $0x4, %rcx
movups 0x7471b2(%rip), %xmm0   # 0x7a2af4
leaq 0x747027(%rip), %rsi    # 0x7a2970
movups %xmm0, (%rcx,%rsi)
movl 0x747211(%rip), %ecx    # 0x7a2b64
leaq 0x747216(%rip), %rsi    # 0x7a2b70
movl %ecx, (%rsi,%rdx,4)
movl $0xffffffff, 0x7472db(%rip) # imm = 0xFFFFFFFF
movb $-0x55, 0x7472d8(%rip)  # 0x7a2c46
movb %al, 0x7472d3(%rip)     # 0x7a2c47
movb 0x747192(%rip), %cl     # 0x7a2b0c
movb %cl, 0x7472c8(%rip)     # 0x7a2c48
movb 0x7471da(%rip), %cl     # 0x7a2b60
movb %cl, 0x7472bd(%rip)     # 0x7a2c49
movw $0xa, 0x7472ab(%rip)    # 0x7a2c40
xorl %edx, %edx
movl $0xb, %ecx
movzbl %dh, %esi
shll $0x8, %edx
movzwl %dx, %edx
movzbl -0x2(%rcx,%r12), %edi
xorl %esi, %edi
xorl (%r14,%rdi,4), %edx
decq %rcx
cmpq $0x1, %rcx
ja 0x5b99c
movw %dx, 0x747289(%rip)     # 0x7a2c4a
movl %eax, %edi
movq %r12, %rsi
movl $0xc, %edx
callq 0x5a549
jmp 0x5b6a5
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x5ba4b
movl 0x74712b(%rip), %ebx    # 0x7a2b10
testl %ebx, %ebx
js 0x5ba4b
cmpl $0x0, 0x84e78(%rip)     # 0xe0868
movl 0x74710e(%rip), %eax    # 0x7a2b04
setne %dl
cmpl 0x747111(%rip), %eax    # 0x7a2b10
sete %cl
orb %dl, %cl
leaq 0x747335(%rip), %r14    # 0x7a2d40
leaq 0x74736e(%rip), %rdx    # 0x7a2d80
leaq 0x747107(%rip), %r10    # 0x7a2b20
movl %ebx, %r15d
cmpl %eax, %ebx
je 0x5ba3f
movl (%r14,%r15,4), %ebp
movl %ebp, %esi
andl $0x1ff, %esi            # imm = 0x1FF
movq %r15, %r9
shlq $0xb, %r9
addq %rdx, %r9
movslq (%r9,%rsi,4), %r8
testq %r8, %r8
jne 0x5ba60
testb %cl, %cl
je 0x5ba4b
movl (%r10,%r15,4), %ebx
testl %ebx, %ebx
jns 0x5ba19
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq (%r9,%rsi,4), %r12
leaq 0x757395(%rip), %rax    # 0x7b2e00
leaq (%r8,%rax), %rsi
addq $0x2, %rsi
movswq -0x2(%rsi), %r13
movq %r13, %rdx
callq 0x80e0
movq 0x8(%rsp), %rcx
movl %ebx, (%rcx)
movl $0x0, (%r12)
incl %ebp
movl %ebp, (%r14,%r15,4)
jmp 0x5ba4e