// File: /workspace/github_c_makefile_star2_O2/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 %r15d, %r15d
cmpl $0x2, 0x7472aa(%rip)    # 0x79bb2c
jl 0x54da5
movq %rsi, 0x8(%rsp)
movq %rdi, 0x10(%rsp)
cmpl $0x0, 0x7472e7(%rip)    # 0x79bb80
je 0x548df
leaq 0x74728e(%rip), %rax    # 0x79bb30
leaq 0x747297(%rip), %rbx    # 0x79bb40
movslq (%rax), %r15
testq %r15, %r15
js 0x548df
cmpl 0x74726c(%rip), %r15d   # 0x79bb24
je 0x548c2
movl %r15d, %edi
callq 0x54e34
cmpl $0x0, 0x84f9f(%rip)     # 0xd9868
jne 0x548d9
movl 0x747253(%rip), %eax    # 0x79bb24
cmpl 0x747259(%rip), %eax    # 0x79bb30
jne 0x548df
leaq (%rbx,%r15,4), %rax
jmp 0x548a9
callq 0x54db7
movl %eax, 0x74729a(%rip)    # 0x79bb84
leaq 0x74736f(%rip), %r15    # 0x79bc60
leaq 0x4(%rsp), %rbx
leaq 0x747463(%rip), %rbp    # 0x79bd60
movq %rbx, %rdi
movq %r15, %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x53c1f
testl %eax, %eax
je 0x54cfc
movzwl 0x747343(%rip), %r13d   # 0x79bc60
cmpl $0xfe, %r13d
ja 0x548fd
movl %r13d, %edi
callq 0x54def
movl %r13d, %ecx
cmpw (%rcx,%r15), %ax
jne 0x548fd
movl 0x747324(%rip), %eax    # 0x79bc62
cmpl $-0x1, %eax
je 0x54a8b
movslq 0x4(%rsp), %r14
leaq 0x74f44d(%rip), %rcx    # 0x7a3da0
cmpl %eax, (%rcx,%r14,4)
jge 0x54964
leaq 0x74f440(%rip), %rcx    # 0x7a3da0
movl %eax, (%rcx,%r14,4)
leal 0x100(%rax), %edx
leaq 0x74f46f(%rip), %rcx    # 0x7a3de0
movl (%rcx,%r14,4), %ecx
cmpl %ecx, %edx
cmovll %edx, %ecx
xorl %edx, %edx
leaq 0x74741d(%rip), %r9     # 0x79bda0
leaq 0x74f496(%rip), %r10    # 0x7a3e20
leal (%rax,%rdx), %esi
cmpl %ecx, %esi
jge 0x549c4
movl %edx, %edi
sarl $0x3, %edi
movslq %edi, %rdi
movzbl 0x6(%rdi,%r15), %edi
movl %edx, %r8d
andl $0x7, %r8d
btl %r8d, %edi
jae 0x549c0
andl $0x1ff, %esi            # imm = 0x1FF
movq %r14, %rdi
shlq $0xb, %rdi
addq %r10, %rdi
andl $0x0, (%rdi,%rsi,4)
incl %edx
jmp 0x5498a
movl 0x84ea6(%rip), %eax     # 0xd9870
pushq $0x28
popq %rcx
leaq 0x7472b2(%rip), %rdx    # 0x79bc86
movzwl (%rdx), %r13d
testl %r13d, %r13d
je 0x54a70
movslq %ecx, %rbx
movl (%rbx,%r15), %ecx
addl $0x4, %ebx
cmpl (%rbp,%r14,4), %ecx
jl 0x54a5a
andl $0x1ff, %ecx            # imm = 0x1FF
movq %r14, %rdx
shlq $0xb, %rdx
addq %r9, %rdx
cmpl $0x0, (%rdx,%rcx,4)
jne 0x54a5a
leaq (%rdx,%rcx,4), %rcx
leal (%rax,%r13), %edx
cmpl $0x3fffff, %edx         # imm = 0x3FFFFF
pushq $0x1
popq %rdx
cmovgel %edx, %eax
movl %eax, (%rcx)
movslq %eax, %r12
leaq 0x7573f8(%rip), %rcx    # 0x7abe20
movw %r13w, (%r12,%rcx)
leal 0x2(%r12), %eax
movslq %eax, %rdi
addq %rcx, %rdi
movslq %ebx, %rsi
addq %r15, %rsi
movq %r13, %rdx
callq 0x80e0
leaq 0x747353(%rip), %r9     # 0x79bda0
leal (%r12,%r13), %eax
addl $0x2, %eax
movl %eax, 0x84e16(%rip)     # 0xd9870
leal (%rbx,%r13), %ecx
movslq %ecx, %rdx
addq %r15, %rdx
leal (%rbx,%r13), %ecx
addl $0x2, %ecx
jmp 0x549d4
movl 0x74710e(%rip), %eax    # 0x79bb84
leaq 0x747113(%rip), %rcx    # 0x79bb90
movl %eax, (%rcx,%r14,4)
leaq 0x4(%rsp), %rbx
jmp 0x548fd
movzbl 0x7471d4(%rip), %eax    # 0x79bc66
cmpl $0xab, %eax
je 0x54aca
cmpl $0xaa, %eax
jne 0x548fd
cmpl $0x0, 0x84dbd(%rip)     # 0xd9868
movl 0x4(%rsp), %r13d
movl 0x74706e(%rip), %eax    # 0x79bb24
je 0x54b5d
cmpl %eax, %r13d
je 0x548fd
jmp 0x54c39
cmpl $0x0, 0x84d97(%rip)     # 0xd9868
je 0x54ba0
movzbl 0x747189(%rip), %eax    # 0x79bc67
cmpl %eax, 0x747040(%rip)    # 0x79bb24
jne 0x54b18
movzbl 0x74717b(%rip), %eax    # 0x79bc68
cmpl %eax, 0x747039(%rip)    # 0x79bb2c
jne 0x54b18
movslq 0x4(%rsp), %r13
movl %r13d, %edi
callq 0x55091
movl 0x74707c(%rip), %eax    # 0x79bb84
leaq 0x747081(%rip), %rcx    # 0x79bb90
movl %eax, (%rcx,%r13,4)
jmp 0x548fd
cmpb $0x0, 0xb57301(%rip)    # 0xbabe20
jne 0x54b51
leaq 0x746f68(%rip), %rdi    # 0x79ba90
callq 0x544ed
movl 0x4(%rsp), %edx
movzbl 0x74712f(%rip), %ecx    # 0x79bc67
movzbl 0x747128(%rip), %r8d    # 0x79bc68
leaq 0x43fec(%rip), %rdi     # 0x98b33
movq %rax, %rsi
xorl %eax, %eax
callq 0x33127
movb $0x1, 0xb572c8(%rip)    # 0xbabe20
jmp 0x548fd
cmpl %eax, %r13d
jne 0x54c39
cmpl 0x746fc4(%rip), %eax    # 0x79bb30
jne 0x54c39
movslq 0x746fb3(%rip), %rax    # 0x79bb2c
leaq 0x746650(%rip), %rcx    # 0x79b1d0
pushq $0x1
popq %r13
cmpq %rax, %r13
jge 0x54c2a
cmpw $0x0, (%rcx)
je 0x54c34
incq %r13
subq $-0x80, %rcx
jmp 0x54b84
movzbl 0x7470c0(%rip), %ecx    # 0x79bc67
movzbl 0x7470ba(%rip), %eax    # 0x79bc68
cmpb %al, %cl
setae %dl
cmpb $0x10, %al
setae %sil
orb %dl, %sil
jne 0x548fd
movl 0x4(%rsp), %edi
cmpl 0x746f64(%rip), %edi    # 0x79bb30
jne 0x548fd
cmpl %ecx, 0x746f4c(%rip)    # 0x79bb24
jne 0x54be6
cmpl %eax, 0x746f4c(%rip)    # 0x79bb2c
je 0x54cbc
movl %ecx, 0x746f38(%rip)    # 0x79bb24
andl $0x0, 0x746f3d(%rip)    # 0x79bb30
leal -0x1(%rax), %ecx
testl %ecx, %ecx
movl $0x0, %edx
cmovlel %edx, %ecx
movl %eax, 0x746f26(%rip)    # 0x79bb2c
shlq $0x2, %rcx
pushq $0x1
popq %rdx
xorl %esi, %esi
leaq 0x746f2a(%rip), %rdi    # 0x79bb40
cmpq %rsi, %rcx
je 0x54cb5
movl %edx, (%rsi,%rdi)
addq $0x4, %rsi
incl %edx
jmp 0x54c16
movl %r13d, 0x4(%rsp)
jmp 0x548fd
movl %r13d, 0x4(%rsp)
testl %r13d, %r13d
js 0x548fd
movl %r13d, %edi
callq 0x55091
movl 0x746f34(%rip), %eax    # 0x79bb84
movl %r13d, %ecx
orl $-0x1, 0x747008(%rip)   # 0x79bc62
leaq 0x746f2f(%rip), %rdx    # 0x79bb90
movl %eax, (%rdx,%rcx,4)
movb $-0x55, 0x746ffb(%rip)  # 0x79bc66
movb %r13b, 0x746ff5(%rip)   # 0x79bc67
movb 0x746eb4(%rip), %al     # 0x79bb2c
movb %al, 0x746fea(%rip)     # 0x79bc68
movb 0x746efc(%rip), %al     # 0x79bb80
movb %al, 0x746fdf(%rip)     # 0x79bc69
movw $0xa, 0x746fcd(%rip)    # 0x79bc60
pushq $0xa
popq %rdi
callq 0x54def
movw %ax, 0x746fc8(%rip)     # 0x79bc6a
movl %r13d, %edi
movq %r15, %rsi
pushq $0xc
popq %rdx
callq 0x53ab2
jmp 0x548fd
orl $-0x1, -0x4(%rdi,%rax,4)
xorl %edi, %edi
cmpl $0x0, 0x746ebd(%rip)    # 0x79bb80
setne %al
cmpb $0x0, 0x746f9c(%rip)    # 0x79bc69
setne %cl
orb %al, %cl
movzbl %cl, %eax
movl %eax, 0x746ea5(%rip)    # 0x79bb80
callq 0x55091
movl 0x746e9e(%rip), %eax    # 0x79bb84
movslq 0x746e43(%rip), %rcx    # 0x79bb30
leaq 0x746e9c(%rip), %rdx    # 0x79bb90
movl %eax, (%rdx,%rcx,4)
jmp 0x548fd
xorl %r15d, %r15d
cmpq $0x0, 0x8(%rsp)
je 0x54da5
movl 0x746e13(%rip), %eax    # 0x79bb24
cmpl $0x0, 0x84b50(%rip)     # 0xd9868
setne %dl
movl 0x746e0f(%rip), %ebx    # 0x79bb30
cmpl %ebx, %eax
sete %cl
orb %dl, %cl
leaq 0x746e11(%rip), %r8     # 0x79bb40
leaq 0x74706a(%rip), %r9     # 0x79bda0
testl %ebx, %ebx
js 0x54da5
movl %ebx, %r14d
cmpl %eax, %ebx
je 0x54d62
movl (%rbp,%r14,4), %r12d
movl %r12d, %edx
andl $0x1ff, %edx            # imm = 0x1FF
movq %r14, %rsi
shlq $0xb, %rsi
addq %r9, %rsi
movslq (%rsi,%rdx,4), %rdi
testq %rdi, %rdi
jne 0x54d6c
testb %cl, %cl
je 0x54da5
movl (%r8,%r14,4), %ebx
jmp 0x54d36
leaq (%rsi,%rdx,4), %r13
leaq 0x7570a9(%rip), %rax    # 0x7abe20
leaq (%rdi,%rax), %rsi
addq $0x2, %rsi
movswq -0x2(%rsi), %r15
movq 0x8(%rsp), %rdi
movq %r15, %rdx
callq 0x80e0
movq 0x10(%rsp), %rax
movl %ebx, (%rax)
andl $0x0, (%r13)
incl %r12d
movl %r12d, (%rbp,%r14,4)
movl %r15d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq