// Extracts a file (PRG, SEQ) byte-by-byte to stdout. void read_file(char *d, int track, int sector) { char *b = BLOCK(d, track, sector); while (b) { if (b[0]) { write(1, &b[2], 254); } else { write(1, &b[2], (unsigned char)b[1]-1); } b = nextblock(d, b); } }
// Calculate exact file size by reading entire file. // Fast since its all in ram. int file_size(char *d, int track, int sector) { int size = 0; char *b = BLOCK(d, track, sector); while (b) { if (b[0]) { size += 254; } else { size += (unsigned char)b[1]-1; } b = nextblock(d, b); } return size; }
int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stdout, "Usage: %s <disk.d64> [track] [sector]\n", argv[0]); return 1; } char *d = load_disk(argv[1]); if (argc == 4) { read_file(d, atoi(argv[2]), atoi(argv[3])); return 0; } char label[19]; // Includes null & quotes // Read Disk header char *b = BLOCK(d, DIR_TRACK, 0); // Volume label #ifdef D1581 trim(&label[1], &b[4], sizeof(label)-2); label[0] = '"'; strcat(label, "\""); printf("0 %s %c %c\n", label, b[0x19], b[0x1a]); #else trim(&label[1], &b[0x90], sizeof(label)-2); label[0] = '"'; strcat(label, "\""); printf("0 %s %2.2s %2.2s\n", label, &b[0xa2], &b[0xa5]); #endif assert(b[0] == DIR_TRACK); #ifdef D1581 assert(b[1] == 3); assert(b[2] == 'D'); #else assert(b[1] == 1); assert(b[2] == 'A'); #endif //hexdump(b); //write(1, &b[0x90], 16); lsdir(d, nextblock(d, b)); printf("%d BLOCKS FREE.\n", compute_blocks_free(&b[0])); }
void lsdir(char *d, char *b) { struct dir_entry *e; char fn[19]; // Includes null & quotes fn[0]= '"'; while (b) { for (int i=0; i<BLK_SIZE; i+=sizeof(*e)) { e = (struct dir_entry*)(&b[i]); if (e->type) { int size = e->file_size_low + 256*e->file_size_high; trim(&fn[1], e->filename, sizeof(fn)-2); strcat(fn, "\""); printf("%-4d %-18s %s%s (%d,%d) [%d bytes]\n", size, fn, filetype(e->type), filebits(e->type), e->track, e->sector, file_size(d, e->track, e->sector)); } } b = nextblock(d, b); } }
STATIC struct block * new_block() { register struct block *pblock = maxblocklist - 1; if (!maxblocklist || !(pblock->b_flags & PARTLY)) { /* * There is no last block, or it was filled completely, * so allocate a new blockheader. */ register int siz; pblock = blocklist; if (maxblocklist == topblocklist) { /* * No blockheaders left. Allocate new ones */ siz = topblocklist - pblock; blocklist = pblock = (struct block *) re_alloc((char *) pblock, (unsigned) (siz * sizeof(*pblock)), (unsigned) ((siz + CHUNK) * sizeof(*pblock))); pblock += siz; topblocklist = pblock + CHUNK; maxblocklist = pblock; for (; pblock < topblocklist; pblock++) { pblock->b_end = 0; pblock->b_info = 0; pblock->b_flags = 0; } if (!siz) { /* * Create dummy header cell. */ maxblocklist++; } } pblock = maxblocklist++; } nextblock(pblock); return pblock; }
void start(){ initscr(); srand(time(0)); init_background(0,0); refresh(); keypad(stdscr,TRUE); pthread_t keyboard; //键盘监听线程 int err = init_network(); //初始化网络模块 if(err!=0){ mvprintw(5,60,"Network model init failed!"); } start: initpanel(); //把两个panel清空 initblock(b1);initblock(b2); printpanel(PANELSTARTX,PANELSTARTY); err = pthread_create(&keyboard,NULL,keylistener,NULL); if(err !=0){ printf("can't create thread keyboard listener!"); exit(1); } //main thread make the block moving down until the gameover while(!over){ movemid(); if(caninput(b1)){ //可以放下当前块说明游戏未结束 while( canmovedown() ){ //直到不能下落位置 //继续下落 goahead(); //显示一次 printpanel(PANELSTARTX,PANELSTARTY); usleep(sleeptime); } //save temp panel to preview panel and create new block savetoprev(); printpanel(PANELSTARTX,PANELSTARTY); //停止下落后要消除 eliminate(); //把下一个块替换上来 nextblock(); } else over=true; } attrset(COLOR_PAIR(7)); mvprintw(21,37,"YOU DEAD!Try again?(y/n):"); int input; int quit = 1; while(quit){ input=getch(); //判断用户还要不要玩下去 switch(input){ case 'y': over = 0; attrset(COLOR_PAIR(0)); mvprintw(21,37," "); goto start; //重新开始 break; case 'n': endwin();quit = 0;break; default: mvprintw(21,37,"YOU DEAD!Try again?(y/n):"); } } }