static void writeblob(FILE *fd, Blob *b) { size_t i; if (!b) return; if (b->lbl) { if (b->iscomdat) emitonce(fd, b); if (b->isglobl) fprintf(fd, ".globl %s%s\n", Symprefix, b->lbl); fprintf(fd, "%s%s:\n", Symprefix, b->lbl); } switch (b->type) { case Btimin: encodemin(fd, b->ival); break; case Bti8: fprintf(fd, "\t.byte %zd\n", b->ival); break; case Bti16: fprintf(fd, "\t.short %zd\n", b->ival); break; case Bti32: fprintf(fd, "\t.long %zd\n", b->ival); break; case Bti64: fprintf(fd, "\t.quad %zd\n", b->ival); break; case Btbytes: writebytes(fd, b->bytes.buf, b->bytes.len); break; case Btpad: fprintf(fd, "\t.fill %zd,1,0\n", b->npad); break; case Btref: fprintf(fd, "\t.quad %s + %zd\n", b->ref.str, b->ref.off); break; case Btseq: for (i = 0; i < b->seq.nsub; i++) writeblob(fd, b->seq.sub[i]); break; } if (b->lbl && b->iscomdat) fprintf(fd, ".text\n"); }
void sock_sendplayer() { char s[3] = "p"; s[1] = player1.startlevel; s[2] = player1.rotationsys; writebytes(s, 3); }
void read_from_clients(fd_set *fdset) { char buf[48]; int i; int sock; int n; for (i=0; i < num_clients; i++) { sock = clients[i].sock; if (!FD_ISSET(sock, fdset)) continue; if (!readbytes(sock, buf, 1) || buf[0] >= '\t' && buf[0] < '\033') { i = remove_client(i); continue; } n = 0; switch (buf[0]) { case 'N': if (readbytes(sock, buf+1, 1)) { if (buf[1] == '_') { send_opponent_name(i); continue; } if (readbytes(sock, buf+2, 15)) { memcpy(clients[i].name, buf+1, 16); continue; } } i = remove_client(i); continue; case 'b': case 'g': case 'h': case 'w': n = 1; break; case 'p': writebytes(sock, "N_", 2); case 'm': case 'n': n = 2; break; case 'x': n = 4; } if (n && !readbytes(sock, buf+1, n) || !fwd_to_opponent(i, buf, n+1)) i = remove_client(i); else if (buf[0] == 'b') { n = buf[1]; if (n > 0 && n <= 12) { n *= 4; if (!readbytes(sock, buf, n) || !fwd_to_opponent(i, buf, n)) i = remove_client(i); } } } }
static void initgame_response() { char s[3] = "m"; sock_sendplayer(); s[1] = game->mode; s[2] = player1.lineslimit; writebytes(s, 3); }
int fwd_to_opponent(int i, const char *buf, int n) { if (i % 2 == 0) i++; else i--; return i == num_clients || writebytes(clients[i].sock, buf, n); }
void sock_sendnext(const struct player *p, char n) { char s[3] = "n"; if (sock_flags & PL2_IN_GAME) { s[1] = '1'+(p == game->player); s[2] = n; writebytes(s, 3); } }
void sock_initround() { char s[3] = "n1"; sock_flags &= ~PL2_GARBAGE; sock_sendbyte('G'); if (is_server) { s[2] = *tetrom_seq; writebytes(s, 3); s[1] = '2'; writebytes(s, 3); s[2] = tetrom_seq[1]; writebytes(s, 3); s[1] = '1'; writebytes(s, 3); } if (player1.height) sendboard(p1_height_lines()); }
void sock_sendpiece(const struct player *p) { char s[5] = "x"; if (sock_flags & PL2_IN_GAME) { int bl = player1.piece.blocks; s[1] = bl & 0xFF; s[2] = bl>>8; memcpy(s+3, &player1.piece.x, 2); writebytes(s, 5); }
static void sendname() { char s[17] = "N"; int i = 0; while (my_name[i] == '_') i++; if (my_name[i]) { strncpy(s+1, my_name+i, 16); writebytes(s, 17); } }
static void recvplayer() { char s[2]; if (readbytes(s, 2)) { if (s[0] > 9 || s[0] < 0) { sock_flags |= CONN_BROKEN; return; } player2.startlevel = s[0]; player2.rotationsys = s[1]; writebytes("N_", 2); } }
void send_opponent_name(int i) { char buf[17] = "N"; int sock = clients[i].sock; if (i % 2 == 0) i++; else i--; if (i < num_clients) { copy_name(buf+1, clients[i].name); writebytes(sock, buf, 17); } }
void genstrings(FILE *fd, Htab *strtab) { void **k; Str *s; size_t i, nk; k = htkeys(strtab, &nk); for (i = 0; i < nk; i++) { s = k[i]; fprintf(fd, "%s:\n", (char*)htget(strtab, k[i])); writebytes(fd, s->buf, s->len); } }
static size_t writeblob(FILE *fd, Blob *b, size_t off, char *lbl) { size_t i, n; n = 0; if (!b) return 0; switch (b->type) { case Bti8: fprintf(fd, "DATA %s+%zd(SB)/1,$%zd\n", lbl, off+n, b->ival); n += 1; break; case Bti16: fprintf(fd, "DATA %s+%zd(SB)/2,$%zd\n", lbl, off+n, b->ival); n += 2; break; case Bti32: fprintf(fd, "DATA %s+%zd(SB)/4,$%zd\n", lbl, off+n, b->ival); n += 4; break; case Bti64: fprintf(fd, "DATA %s+%zd(SB)/8,$%lld\n", lbl, off+n, (vlong)b->ival); n += 8; break; case Btimin: n += encodemin(fd, b->ival, off+n, lbl); break; case Btref: if (b->ref.isextern || b->ref.str[0] == '.') fprintf(fd, "DATA %s+%zd(SB)/8,$%s+%zd(SB)\n", lbl, off+n, b->ref.str, b->ref.off); else fprintf(fd, "DATA %s+%zd(SB)/8,$%s<>+%zd(SB)\n", lbl, off+n, b->ref.str, b->ref.off); n += 8; break; case Btbytes: n += writebytes(fd, lbl, off+n, b->bytes.buf, b->bytes.len); break; case Btseq: for (i = 0; i < b->seq.nsub; i++) n += writeblob(fd, b->seq.sub[i], off+n, lbl); break; case Btpad: for (i = 0; i < b->npad; i++) fprintf(fd, "DATA %s+%zd(SB)/1,$0\n", lbl, off+n+i); n += b->npad; break; } return n; }
void accept_conn(int sock) { struct sockaddr_in name; socklen_t len = sizeof(name); sock = accept(sock, (struct sockaddr *) &name, &len); if (sock < 0) { perror("accept"); exit(1); } printf("connect from host %s\n", inet_ntoa(name.sin_addr)); clients[num_clients].sock = sock; strncpy(clients[num_clients].name, inet_ntoa(name.sin_addr), 16); writebytes(sock, !(num_clients % 2) ? "P1" : "P2", 2); }
int writebytes(int sock, const char *buf, int n) { int i = send(sock, buf, n, 0); if (i == n) return 1; if (i < 0) { if (errno != EINTR) { perror("send"); return 0; } i = 0; } return writebytes(sock, buf+i, n-i); }
static void genstrings(FILE *fd, Htab *strtab) { void **k; char *lbl; Str *s; size_t i, nk; k = htkeys(strtab, &nk); for (i = 0; i < nk; i++) { s = k[i]; lbl = htget(strtab, k[i]); if (s->len) { fprintf(fd, "GLOBL %s+0(SB),$%lld\n", lbl, (vlong)s->len); writebytes(fd, lbl, 0, s->buf, s->len); } } }
int sock_wait_pl2ingame() { print_game_message(1, "WAIT", 1); game->next = NULL; while (!(sock_flags & CONNECTED)) if (getkey_cancel()) return 0; writebytes("N_G", 3); sock_flags = WAIT_PL2INGAME | (sock_flags & ~SAME_HEIGHT); while (!(sock_flags & PL2_IN_GAME)) { if ((sock_flags & (CONN_PROXY | WAIT_PL2INGAME)) == CONN_PROXY) return sock_wait_pl2ingame(); if (getkey_cancel()) break; } sock_flags &= ~WAIT_PL2INGAME; return sock_flags & PL2_IN_GAME; }
int remove_client(int i) { int sock = clients[i].sock; close(sock); num_clients--; printf("player %d disconnected\n", i+1); if (i % 2 == 0) sock = clients[i+1].sock; else sock = clients[--i].sock; if (i < num_clients) { memmove(clients+i, clients+i+2, (num_clients-i-1)*sizeof(struct client)); if (num_clients % 2 == 0) { close(sock); num_clients--; } else { clients[num_clients-1].sock = sock; writebytes(sock, "\033P1", 3); } } return i-1; }
static void sendboard(int n) { char s[50] = "b"; unsigned char *b; uint_least32_t row; int i, j; if (!(sock_flags & PL2_IN_GAME)) return; s[1] = n; b = (unsigned char *) s + 2; i = 20; while (n) { row = player1.board[--i]; j = 0; do { b[j] = row & 0xFF; j++; } while (row >>= 8); b += 4; n--; } writebytes(s, (char *)b - s); }
/*----------------------------------------------------------------------- * Copy memory to flash. */ int write_buff (unsigned char * src, unsigned long addr, unsigned long cnt) { int rc; unsigned long i; unsigned long blockaddr; unsigned long destaddr; unsigned long lpacket; if((addr < CFG_FLASH_BASE) || (addr >= (CFG_FLASH_BASE + 64 * 128 * 1024))) return ERR_INVAL; i = 0; blockaddr = CFG_FLASH_BASE; do { blockaddr += 128*1024; }while(blockaddr <= addr); blockaddr = blockaddr - 128*1024; destaddr = addr; if(cnt == 1) { rc = write_byte (addr, *src); //只有一个字节,直接写入完毕 return rc; } lpacket = 0x20 - (addr & 0x1f); if(lpacket < cnt) writebytes(src, blockaddr, destaddr, lpacket); else { writebytes(src, blockaddr, destaddr, cnt); // 没有到边界,直接一次写入完毕 return ERR_OK; } destaddr += lpacket; src += lpacket; lpacket = cnt - lpacket; while(lpacket > 32) { do { blockaddr += 128*1024; }while(blockaddr <= destaddr); blockaddr = blockaddr - 128*1024; writebytes(src, blockaddr, destaddr, 32); // 循环写入32字节数据 src += 32; destaddr += 32; lpacket -= 32; } if(lpacket != 0) { do { blockaddr += 128*1024; }while(blockaddr <= destaddr); blockaddr = blockaddr - 128*1024; writebytes(src, blockaddr, destaddr, lpacket); } return ERR_OK; }
compress() { register long fcode; register code_int i = 0; register int c; register code_int ent; #ifdef XENIX_16 register code_int disp; #else /* Normal machine */ register int disp; #endif register code_int hsize_reg; register int hshift; #ifndef COMPATIBLE if (nomagic == 0) { putbyte(magic_header[0]); putbyte(magic_header[1]); putbyte((char)(maxbits | block_compress)); } #endif /* COMPATIBLE */ offset = 0; bytes_out = 3; /* includes 3-byte header mojo */ out_count = 0; clear_flg = 0; ratio = 0; in_count = 1; checkpoint = CHECK_GAP; maxcode = MAXCODE(n_bits = INIT_BITS); free_ent = ((block_compress) ? FIRST : 256 ); ent = getbyte (); hshift = 0; for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L ) hshift++; hshift = 8 - hshift; /* set hash code range bound */ hsize_reg = hsize; cl_hash( (count_int) hsize_reg); /* clear hash table */ #ifdef SIGNED_COMPARE_SLOW while ( (c = getbyte()) != (unsigned) EOF ) { #else while ( (c = getbyte()) != EOF ) { #endif in_count++; fcode = (long) (((long) c << maxbits) + ent); i = ((c << hshift) ^ ent); /* xor hashing */ if ( htabof (i) == fcode ) { ent = codetabof (i); continue; } else if ( (long)htabof (i) < 0 ) /* empty slot */ goto nomatch; disp = hsize_reg - i; /* secondary hash (after G. Knott) */ if ( i == 0 ) disp = 1; probe: if ( (i -= disp) < 0 ) i += hsize_reg; if ( htabof (i) == fcode ) { ent = codetabof (i); continue; } if ( (long)htabof (i) > 0 ) goto probe; nomatch: output ( (code_int) ent ); out_count++; ent = c; #ifdef SIGNED_COMPARE_SLOW if ( (unsigned) free_ent < (unsigned) maxmaxcode) { #else if ( free_ent < maxmaxcode ) { #endif codetabof (i) = free_ent++; /* code -> hashtable */ htabof (i) = fcode; } else if ( (count_int)in_count >= checkpoint && block_compress ) cl_block (); } /* * Put out the final code. */ output( (code_int)ent ); out_count++; output( (code_int)-1 ); /* * Print out stats on stderr */ if(zcat_flg == 0 && !quiet) { #ifdef DEBUG fprintf( stderr, "%ld chars in, %ld codes (%ld bytes) out, compression factor: ", in_count, out_count, bytes_out ); prratio( stderr, in_count, bytes_out ); fprintf( stderr, "\n"); fprintf( stderr, "\tCompression as in compact: " ); prratio( stderr, in_count-bytes_out, in_count ); fprintf( stderr, "\n"); fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n", free_ent - 1, n_bits ); #else /* !DEBUG */ fprintf( stderr, "Compression: " ); prratio( stderr, in_count-bytes_out, in_count ); #endif /* DEBUG */ } if(bytes_out > in_count) /* exit(2) if no savings */ exit_stat = 2; return; } /***************************************************************** * TAG( output ) * * Output the given code. * Inputs: * code: A n_bits-bit integer. If == -1, then EOF. This assumes * that n_bits =< (long)wordsize - 1. * Outputs: * Outputs code to the file. * Assumptions: * Chars are 8 bits long. * Algorithm: * Maintain a BITS character long buffer (so that 8 codes will * fit in it exactly). Use the VAX insv instruction to insert each * code in turn. When the buffer fills up empty it and start over. */ static char buf[BITS]; char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; output( code ) code_int code; { #ifdef DEBUG static int col = 0; #endif /* DEBUG */ /* * On the VAX, it is important to have the register declarations * in exactly the order given, or the asm will break. */ register int r_off = offset, bits= n_bits; register char * bp = buf; #ifdef DEBUG if ( verbose ) fprintf( stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' ); #endif /* DEBUG */ if ( code >= 0 ) { /* * byte/bit numbering on the VAX is simulated by the following code */ /* * Get to the first byte. */ bp += (r_off >> 3); r_off &= 7; /* * Since code is always >= 8 bits, only need to mask the first * hunk on the left. */ *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off]; bp++; bits -= (8 - r_off); code >>= 8 - r_off; /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if ( bits >= 8 ) { *bp++ = code; code >>= 8; bits -= 8; } /* Last bits. */ if(bits) *bp = code; offset += n_bits; if ( offset == (n_bits << 3) ) { bp = buf; bits = n_bits; bytes_out += bits; do putbyte(*bp++); while(--bits); offset = 0; } /* * If the next entry is going to be too big for the code size, * then increase it, if possible. */ if ( free_ent > maxcode || (clear_flg > 0)) { /* * Write the whole buffer, because the input side won't * discover the size increase until after it has read it. */ if ( offset > 0 ) { writebytes( buf, n_bits ); bytes_out += n_bits; } offset = 0; if ( clear_flg ) { maxcode = MAXCODE (n_bits = INIT_BITS); clear_flg = 0; } else { n_bits++; if ( n_bits == maxbits ) maxcode = maxmaxcode; else maxcode = MAXCODE(n_bits); } #ifdef DEBUG if ( debug ) { fprintf( stderr, "\nChange to %d bits\n", n_bits ); col = 0; } #endif /* DEBUG */ } } else { /* * At EOF, write the rest of the buffer. */ if ( offset > 0 )
void sock_sendbyte(char b) { writebytes(&b, 1); }