void remove_complete_lines(void) { char s[8]; byte row, x, y, complete; for (row = curr_y - 1; row < curr_y + 3 && row < PLAYF_HEIGHT; row++) { complete = 1; for (x = 0; x < PLAYF_WIDTH && complete; x++) { if (!is_block_set(x, row)) complete = 0; } if (complete) { for (y = row; y > 0; y--) { for (x = 0; x < PLAYF_WIDTH; x++) { if (is_block_set(x, y - 1)) draw_block(x, y); else clear_block(x, y); } } lines++; buf2screen(); } } itoa(lines, s); vputs(100, 80, "LINES "); vputs(135, 80, s); }
/* * Clear to the end of the current physical line */ void vclreol(void) { register int i; register char *tp; if (destcol == VCOLUMNS) return; destline += destcol / VCOLUMNS; destcol %= VCOLUMNS; #ifdef DEBUG if (destline < 0 || destline > TUBELINES) error("Internal error: vclreol@- please tell someone"); #endif i = VCOLUMNS - destcol; tp = vtube[destline] + destcol; if (*tp == 0) return; if (CE) { vcsync(); vputs(CE); vclrbyte(tp, i); return; } while (i > 0 && *tp != 0) { vputchar(' '); --i, tp++; } }
void draw_playfield(void) { byte x, y; for (y = PLAYF_Y - 2; y < PLAYF_Y + PLAYF_HEIGHT * BLOCK_SIZE + 1; y++) { if (y & 1) { setpixel(PLAYF_X - 1, y); setpixel(PLAYF_X + PLAYF_WIDTH * BLOCK_SIZE, y); } else { setpixel(PLAYF_X - 2, y); setpixel(PLAYF_X + PLAYF_WIDTH * BLOCK_SIZE + 1, y); } } for (x = PLAYF_X - 2; x < PLAYF_X + PLAYF_WIDTH * BLOCK_SIZE + 2; x++) { if (x & 1) { setpixel(x, PLAYF_Y + PLAYF_HEIGHT * BLOCK_SIZE); } else { setpixel(x, PLAYF_Y + PLAYF_HEIGHT * BLOCK_SIZE + 1); } } vputs(100, 5, "TETRIS"); line(PREVIEW_X, PREVIEW_Y, PREVIEW_X + 30, PREVIEW_Y); line(PREVIEW_X, PREVIEW_Y + 30, PREVIEW_X + 30, PREVIEW_Y + 30); line(PREVIEW_X, PREVIEW_Y, PREVIEW_X, PREVIEW_Y + 30); line(PREVIEW_X + 30, PREVIEW_Y, PREVIEW_X + 30, PREVIEW_Y + 30); buf2screen(); }
void vprintf(struct virtscreen *vscr, char *fmt, ...) { static char line[128]; va_list pvar; va_start(pvar,fmt); va_snprintf(line,128,fmt,pvar); line[127]=0; va_end(pvar); vputs(vscr,line); }
void printf(char *fmt, ...) { static char line[128]; va_list pvar; va_start(pvar,fmt); va_snprintf(line,128,fmt,pvar); line[127]=0; va_end(pvar); vputs(active,line); }
/* * Clear the entire (physical and logical) screen */ void vclear(void) { vputs(CLEAR); destcol = 0; outcol = 0; destline = 0; outline = 0; vclrbyte(vtube0, LINES * COLUMNS); }
short rd_scor () { sprintf (dspbuf, "%02.2d", curscor + 1); if (v_regs[5] & 0x0180) vbank (0); vputs (obj8, 8, 7, dspbuf, SDW13ATR); return (SUCCESS); }
short rd_strn () { sprintf (dspbuf, "%c%02d", grptran < 0 ? '-' : '+', abs (grptran)); if (v_regs[5] & 0x0180) vbank (0); vputs (obj8, 7, 22, dspbuf, SDMENUBG); return (SUCCESS); }
// Find key(s) bound to given command, convert to string form (if not prefixed), and store in dest. Return status. If c is // non-zero, process "line" command. Used by bpop() for help prompt. static int hkey(StrList *destp,int (*cfunc)(Value *rp,int n),int c) { KeyWalk kw = {NULL,NULL}; KeyDesc *kdp; char *strp,wkbuf[16]; bool found = false; // Initialize leading literal. strp = c ? " (" : ","; // Search binding table for any keys bound to command. kdp = nextbind(&kw); do { if(kdp->k_cfab.p_type == PTRCMD && kdp->k_cfab.u.p_cfp->cf_func == cfunc) { // Found one. Prefixed? if((kdp->k_code & KEYSEQ) == 0) { // No. Save it. if(vputs(strp,destp) != 0) return vrcset(); strp = ","; if(vputs(ektos(kdp->k_code,wkbuf),destp) != 0) return vrcset(); found = true; } } } while((kdp = nextbind(&kw)) != NULL); // Return now if no keys found or not a "line" command. if(!found || !c) return rc.status; // One or more keys found. Finish up "line" command. return vputf(destp,") %c%s",c,text205) == 0 ? rc.status : vrcset(); // "line" }
void console_thread(void) { int l, src; uint32 code; char data[257]; #ifdef CONSOLE_DEBUG vprintf(active, "console: " FG_GREEN "listener ready" FG_WHITE " (port %d)\n",console_port); #endif while((l = port_recv(console_port, &src, data, 256, &code)) >= 0){ if(code == 0) { remote_port = src; } else { data[l] = 0; vputs(active, data); } } vprintf(active, "console: output listener has left the building (%d)\n",l); os_terminate(0); }
int console_main(void) { int err,i; area_create(0x2000, 0, &screen, AREA_PHYSMAP); console_port = port_create(0,"console_listen_port"); send_port = port_create(0,"console_send_port"); port_option(send_port, PORT_OPT_NOWAIT, 1); err = namer_register(console_port,"console"); init_virtscreen(&statbar, 1, 80); statbar.back = statbar.data; statbar.data = (unsigned short *) (((uint32) screen) + 80*24*2); statbar.lock = sem_create(1,"statbar_lock"); for(i=0;i<10;i++){ init_virtscreen(&con[i], 24, 80); con[i].back = con[i].data; con[i].lock = sem_create(1,"vscr_lock"); vputs(&con[i],CLEAR); } load(&con[0]); status(0); if(err) vprintf(active,"console: the namer hates us\n"); else #ifdef CONSOLE_DEBUG vprintf(active,"console: " FG_GREEN "online." FG_WHITE "\n"); #else ; #endif thr_create(keyboard_irq_thread, NULL, "console:kbd"); ready = 1; console_thread(); return 0; }
// Build and pop up a buffer containing a list of all screens and their associated buffers. Render buffer and return status. int showScreens(Value *rp,int n) { Buffer *slistp; EScreen *scrp; // Pointer to current screen to list. EWindow *winp; // Pointer into current screens window list. uint wnum; StrList rpt; int windcol = 7; int filecol = 37; char *strp,wkbuf[filecol + 16]; // Get a buffer and open a string list. if(sysbuf(text160,&slistp) != SUCCESS) // "Screens" return rc.status; if(vopen(&rpt,NULL,false) != 0) return vrcset(); // Construct the header lines. if(vputs(text89,&rpt) != 0 || vputc('\n',&rpt) != 0 || // "Screen Window Buffer File" vputs("------ ------ -------------------- -------------------------------",&rpt) != 0) return vrcset(); // For all screens... scrp = sheadp; do { // Store the screen number. sprintf(wkbuf,"\n%4hu ",scrp->s_num); strp = strchr(wkbuf,'\0'); // List screen's window numbers and buffer names. wnum = 0; winp = scrp->s_wheadp; do { Buffer *bufp = winp->w_bufp; // Indent if not first time through. if(wnum != 0) { wkbuf[0] = '\n'; strp = wkbuf + 1; do { *strp++ = ' '; } while(strp <= wkbuf + windcol); } // Store window number, buffer name, and filename. sprintf(strp,"%4u %c%s",++wnum,(bufp->b_flags & BFCHGD) ? '*' : ' ',bufp->b_bname); strp = strchr(strp,'\0'); if(bufp->b_fname != NULL) // Pad if filename exists. do { *strp++ = ' '; } while(strp <= wkbuf + filecol); *strp = '\0'; // Save buffer and add filename. if(vputs(wkbuf,&rpt) != 0 || (bufp->b_fname != NULL && vputs(bufp->b_fname,&rpt) != 0)) return vrcset(); // On to the next window. } while((winp = winp->w_nextp) != NULL); // On to the next screen. } while((scrp = scrp->s_nextp) != NULL); // Add the results to the buffer. if(vclose(&rpt) != 0) return vrcset(); if(bappend(slistp,rpt.sl_vp->v_strp) != SUCCESS) return rc.status; // Display results. return render(rp,n < 0 ? -2 : n,slistp,RENDRESET | (n != INT_MIN && n < -1 ? RENDALTML : 0)); }
static void report(const char *name, const uchar_t *status, const tain_t *now) { pid_t pid; tain_t when; uint64_t uptime; uchar_t flags; int haslog; char nbuf[NFMT_SIZE]; /* svdef: */ tain_unpack(&when, &status[16]); flags = status[28]; haslog = (flags & SVDEF_FLAG_HASLOG) ? 1 : 0; /* uptime since activation: */ uptime = tain_uptime(now, &when); vputs(name, ": activated ", nfmt_uint64(nbuf, uptime), " seconds"); if(flags & SVDEF_FLAG_CULL){ vputs(", deactivation in progress"); } if(flags & SVDEF_FLAG_CYCLE){ vputs(", flagged for reactivation"); } vputs("\n"); /* main: */ pid = upak32_unpack(&status[30]); tain_unpack(&when, &status[34]); flags = status[46]; uptime = tain_uptime(now, &when); vputs(" main: "); if(pid == 0){ vputs("down ", nfmt_uint64(nbuf, uptime), " seconds"); if(!(flags & SUBSV_FLAG_WANTDOWN)) vputs(", want up!"); if(flags & SUBSV_FLAG_ISONCE) vputs(", flagged once"); }else if((uptime < 1) && !(flags & SUBSV_FLAG_ISRESET)){ /* munge uptime < 1 second to want up: */ vputs("down, want up!"); if(flags & SUBSV_FLAG_ISONCE) vputs(", flagged once"); }else{ vputs((flags & SUBSV_FLAG_ISRESET) ? "resetting " : "up "); vputs(nfmt_uint64(nbuf, uptime), " seconds"); vputs(" (pid ", nfmt_uint32(nbuf, (uint32_t)pid), ")"); if(flags & SUBSV_FLAG_ISPAUSED) vputs(", paused"); if(flags & SUBSV_FLAG_ISONCE) vputs(", flagged once"); } /* log: */ vputs("\n log: "); if(!haslog){ vputs("(no log)\n"); return; } /* else: */ pid = upak32_unpack(&status[48]); tain_unpack(&when, &status[52]); flags = status[64]; uptime = tain_uptime(now, &when); if(pid == 0){ vputs("down ", nfmt_uint64(nbuf, uptime), " seconds"); if(!(flags & SUBSV_FLAG_WANTDOWN)) vputs(", want up!"); if(flags & SUBSV_FLAG_ISONCE) vputs(", flagged once"); }else if((uptime < 1) && !(flags & SUBSV_FLAG_ISRESET)){ /* munge uptime < 1 second to want up: */ vputs("down, want up!"); if(flags & SUBSV_FLAG_ISONCE) vputs(", flagged once"); }else{ vputs((flags & SUBSV_FLAG_ISRESET) ? "resetting " : "up "); vputs(nfmt_uint64(nbuf, uptime), " seconds"); vputs(" (pid ", nfmt_uint32(nbuf, (uint32_t)pid), ")"); if(flags & SUBSV_FLAG_ISPAUSED) vputs(", paused"); if(flags & SUBSV_FLAG_ISONCE) vputs(", flagged once"); } vputs("\n"); return; }
int main(int argc, char *argv[]) { nextopt_t nopt = nextopt_INIT(argc, argv, ":hVb:"); char opt; const char *basedir = NULL; char pathbuf[256]; tain_t now; size_t n; int fd_conn; progname = nextopt_progname(&nopt); while((opt = nextopt(&nopt))){ char optc[2] = {nopt.opt_got, '\0'}; switch(opt){ case 'h': usage(); die(0); break; case 'V': version(); die(0); break; case 'b': basedir = nopt.opt_arg; break; case ':': fatal_usage("missing argument for option -", optc); break; case '?': if(nopt.opt_got != '?'){ fatal_usage("invalid option -", optc); } /* else fallthrough: */ default : die_usage(); break; } } argc -= nopt.arg_ndx; argv += nopt.arg_ndx; if(!*argv){ fatal_usage("missing argument"); } if(!basedir) basedir = getenv("PERP_BASE"); if(!basedir) basedir = "."; if(chdir(basedir) != 0){ fatal_syserr("fail chdir() to ", basedir); } /* connect to control socket: */ n = cstr_vlen(basedir, "/", PERP_CONTROL, "/", PERPD_SOCKET); if(!(n < sizeof pathbuf)){ errno = ENAMETOOLONG; fatal_syserr("failure locating perpd control socket ", basedir, "/", PERP_CONTROL, "/", PERPD_SOCKET); } cstr_vcopy(pathbuf, basedir, "/", PERP_CONTROL, "/", PERPD_SOCKET); fd_conn = domsock_connect(pathbuf); if(fd_conn == -1){ if(errno == ECONNREFUSED){ fatal_syserr("perpd not running on control socket ", pathbuf); }else{ fatal_syserr("failure connecting to perpd control socket ", pathbuf); } } /* uptimes compared to now: */ tain_now(&now); /* loop through service directory arguments and display report: */ for(; *argv != NULL; ++argv){ pkt_t pkt = pkt_INIT(2, 'Q', 16); struct stat st; if(stat(*argv, &st) == -1){ eputs(*argv, ": error: service directory not found"); continue; } if(! S_ISDIR(st.st_mode)){ eputs(*argv, ": error: not a directory"); continue; } if(!(S_ISVTX & st.st_mode)){ vputs(*argv, ": not activated\n"); continue; } upak_pack(pkt_data(pkt), "LL", (uint64_t)st.st_dev, (uint64_t)st.st_ino); if(pkt_write(fd_conn, pkt, 0) == -1){ eputs_syserr("error: ", *argv, ": error writing query"); continue; } if(pkt_read(fd_conn, pkt, 0) == -1){ eputs_syserr("error: ", *argv, ": error reading response"); continue; } if(pkt[0] != 2){ eputs("error: ", *argv, ": unknown packet protocol in reply"); continue; } if(pkt[1] != 'S'){ if(pkt[1] == 'E'){ errno = (int)upak32_unpack(&pkt[3]); eputs_syserr("error: ", *argv, ": error reported in reply"); } else { eputs("error: ", *argv, ": unknown packet type in reply"); } continue; } report(*argv, pkt_data(pkt), &now); } vputs_flush(); die(0); }
// Display a pop-up window and page it for the user. If altmodeline is true, display buffer name and filename (only) on bottom // mode line. If endprompt is true, wait for user to press a key before returning (regardless of page size). Current bindings // (if any) for backPage, forwPage, backLine, and forwLine commands are recognized as well as 'b' (backward page), 'f' or space // (forward page), 'u' (backward half page), 'd' (forward half page), 'g' (goto first page), 'G' (goto last page), ESC or 'q' // (exit), and '?' (help). Any non-navigation key gets pushed back into the input stream to be interpeted later as a command. // Return status. int bpop(Buffer *bufp,bool altmodeline,bool endprompt) { Line *lnp1,*lnp,*lpmax; int crow; // Current screen row number. int disprows; // Total number of display rows. int halfpage; // Rows in a half page. int n; // Rows to move. ushort ek; // Input extended key. char *strp,*strpz; // Line text pointers. char *hprompt = NULL; // Help prompt; bool firstpass = true; // Display special mode line if requested. if(altmodeline) { // Find last window on screen and rewrite its mode line. wupd_modeline(wnextis(NULL),bufp); } // Set up and display a pop-up "window". disprows = term.t_nrow - 2; // Check if buffer will fit on one page and if not, set lpmax to first line of last page. lpmax = NULL; n = 0; for(lnp = lforw(bufp->b_hdrlnp); lnp != bufp->b_hdrlnp; lnp = lforw(lnp)) { if(++n > disprows) { // Find beginning of last page. lpmax = bufp->b_hdrlnp; n = disprows; do { lpmax = lback(lpmax); } while(--n > 0); break; } } // Begin at the beginning. lnp1 = lforw(bufp->b_hdrlnp); halfpage = disprows / 2; n = 0; // Display a page (beginning at line lnp1 + n) and prompt for a naviagtion command. Loop until exit key entered or // endprompt is false and buffer fits on one page (lpmax is NULL). for(;;) { lnp = lnp1; // Moving backward? if(n < 0) { do { // At beginning of buffer? if(lpmax == NULL || lnp1 == lforw(bufp->b_hdrlnp)) break; // No, back up one line. lnp1 = lback(lnp1); } while(++n < 0); } // Moving forward? else if(n > 0) { do { // At end of buffer or max line? if(lpmax == NULL || lnp1 == bufp->b_hdrlnp || lnp1 == lpmax) break; // No, move forward one line. lnp1 = lforw(lnp1); } while(--n > 0); } // Illegal command? if(n != 0 && lnp1 == lnp) // Yes, ignore it. n = 0; else { // Found first row ... display page. lnp = lnp1; crow = 0; do { // At end of buffer? if(lnp == bufp->b_hdrlnp) { // Yes, erase remaining lines on physical screen. while(crow < disprows) { vtmove(crow,0); vteeol(); #if COLOR vscreen[crow]->v_rfcolor = gfcolor; vscreen[crow]->v_rbcolor = gbcolor; #endif vscreen[crow]->v_left = FARRIGHT; vscreen[crow]->v_right = 0; #if COLOR vscreen[crow++]->v_flags |= VFCHGD | VFCOLOR; #else vscreen[crow++]->v_flags |= VFCHGD; #endif } break; } // Update the virtual screen image for this line. Characters past right edge of screen won't be // displayed, so ignore those. vtmove(crow,0); strpz = (strp = ltext(lnp)) + (lused(lnp) <= (int) term.t_ncol ? lused(lnp) : term.t_ncol); while(strp < strpz) vtputc(*strp++); vteeol(); #if COLOR vscreen[crow]->v_rfcolor = gfcolor; vscreen[crow]->v_rbcolor = gbcolor; #endif vscreen[crow]->v_left = FARRIGHT; vscreen[crow]->v_right = 0; #if COLOR vscreen[crow++]->v_flags |= VFCHGD | VFCOLOR; #else vscreen[crow++]->v_flags |= VFCHGD; #endif // On to the next line. lnp = lforw(lnp); } while(crow < disprows); // Screen is full. Copy the virtual screen to the physical screen. if(pupd_all(false) != SUCCESS) return rc.status; // Bail out if called from terminp() and one-page buffer. if(firstpass && !endprompt && lpmax == NULL) goto uexit; firstpass = false; } // Display prompt. mlputs(MLHOME | MLFORCE,hprompt != NULL ? hprompt : lpmax == NULL || lnp1 == lpmax ? text201 : ": "); // "End: " if(TTflush() != SUCCESS) return rc.status; // Get response. for(;;) { // Get a keystroke and decode it. if(getkey(&ek) != SUCCESS) return rc.status; // Exit? if(ek == (CTRL | '[') || ek == 'q') goto uexit; // Forward whole page? if(ek == ' ' || ek == 'f' || iscmd(ek,forwPage)) { n = disprows - overlap; break; } // Forward half page? if(ek == 'd') { n = halfpage; break; } // Backward whole page? if(ek == 'b' || iscmd(ek,backPage)) { n = overlap - disprows; break; } // Backward half page? if(ek == 'u') { n = -halfpage; break; } // Forward a line? if(iscmd(ek,forwLine)) { n = 1; break; } // Backward a line? if(iscmd(ek,backLine)) { n = -1; break; } // First page? if(ek == 'g') { if(lpmax == NULL || lnp1 == lforw(bufp->b_hdrlnp)) n = -1; // Force beep. else { lnp1 = lforw(bufp->b_hdrlnp); n = 0; } break; } // Last page? if(ek == 'G') { if(lpmax == NULL || lnp1 == lpmax) n = 1; // Force beep. else { lnp1 = lpmax; n = 0; } break; } // Help? if(ek == '?') { StrList msg; // Get string list... if(vopen(&msg,NULL,false) != 0) return vrcset(); // build prompt... if(vputs(text202,&msg) != 0) // "(<SPC>,f" return vrcset(); if(hkey(&msg,forwPage,0) != SUCCESS) return rc.status; if(vputs(text203,&msg) != 0) // ") +page (b" return vrcset(); if(hkey(&msg,backPage,0) != SUCCESS) return rc.status; if(vputs(text204,&msg) != 0) // ") -page (d) +half (u) -half" return vrcset(); if(hkey(&msg,forwLine,'+') != SUCCESS || hkey(&msg,backLine,'-') != SUCCESS) return rc.status; if(vputs(text206,&msg) != 0) // " (g) first (G) last (ESC,q) quit (?) help: " return vrcset(); // and display it. if(vclose(&msg) != 0) return vrcset(); mlputs(MLHOME | MLFORCE,msg.sl_vp->v_strp); } else { // Other key. "Unget" the key for reprocessing and return. tungetc(ek); goto uexit; } } } uexit: uphard(); if(endprompt) mlerase(MLFORCE); return rc.status; }
void tetris(void) { char c, part_no; byte i, stop, start; show_splashscreen(); io_write(5, 42); io_write(6, 15); draw_playfield(); start_song(); start = 1; while (1) { if (start) { next_part_no = rand() % 7; lines = 0; curr_y = 10; remove_complete_lines(); clear_next_part(); while (io_read(128) != 255); do { vputs(95, 65, "GET READY"); buf2screen(); delay_ms(300); vputs(95, 65, " "); buf2screen(); delay_ms(300); } while (io_read(128) == 255); start = 0; } stop = 0; curr_x = 5; curr_y = 1; clear_next_part(); part_no = next_part_no; next_part_no = rand() % 7; draw_next_part(); select_part(part_no); draw_curr_part(); buf2screen(); while (!stop) { for (i = 0; i < 20 && !stop; i++) { if (lines < 20) delay_ms(35); else if (lines < 50) delay_ms(25); else if (lines < 70) delay_ms(18); else if (lines < 100) delay_ms(12); else delay_ms(8); if (!stop) { c = io_read(128); if (c == ' ') { // rotate part rotate_curr_part(); buf2screen(); } else if (c == 0) { // left, right, down c = io_read(128); if (c == 75) { // left move_left(); buf2screen(); } else if (c == 77) { // right move_right(); buf2screen(); } else if (c == 80) { // down while (!move_down()) buf2screen(); buf2screen(); stop = 1; } } else if (c == 27) return; } // if (!stop) } if (!stop) { stop = move_down(); buf2screen(); } } remove_complete_lines(); if (curr_y <= 2) { clear_playfield(); vputs(95, 65, "GAME OVER"); buf2screen(); getchar(); vputs(95, 65, " "); start = 1; } } }