int egetch(void) { int rval; while (1) { rval = terminal_getchar(); if (rval != Ctrl('L')) break; screen_redraw(); } return rval; }
/****************************************************************************** * kaypro_scroll * scroll the screen buffer from line top to line scroll_lines-1 * either up or down. scroll up if lines > 0, down if lines < 0 * repeat lines times and mark changes in dirtybuffer ******************************************************************************/ static void kaypro_scroll(int top, int lines) { int x, y; short attr; while (lines) { if (lines > 0) { for( y = top; y < scroll_lines - 1; y++ ) { for( x = 0; x < KAYPRO_SCREEN_W; x++ ) { terminal_putchar(kaypro_terminal, x, y, terminal_getchar(kaypro_terminal, x, y+1)); } } attr = ' '; for (x = 0; x < KAYPRO_SCREEN_W; x++) { terminal_putchar(kaypro_terminal, x, scroll_lines - 1, attr); } lines--; } else { for (y = scroll_lines - 1; y > top; y--) { for (x = 0; x < KAYPRO_SCREEN_W; x++) { terminal_putchar(kaypro_terminal, x, y, terminal_getchar(kaypro_terminal, x, y-1)); } } attr = ' '; for (x = 0; x < KAYPRO_SCREEN_W; x++) { terminal_putchar(kaypro_terminal, x, top, attr); } lines++; } } }
static void kaypro_pixel(int x, int y, int set) { static int attr_bits[4][2] = { { 0x002, 0x001}, { 0x008, 0x004}, { 0x020, 0x010}, {AT_REVERSE, 0x040} }; int cx, cy, offs, bits; short attr; /* The Kaypro 2x font has a 2x4 pattern block graphics */ cx = x / 2; cy = y / 4; offs = cy * KAYPRO_SCREEN_W + cx; attr = terminal_getchar(kaypro_terminal, cx, cy); /* if it is a space, we change it to a graphic space */ if ((attr & 0xff) == ' ') attr = (attr & 0xff00) | 0x80; /* if it is non graphics, we do nothing */ if (! (attr & 0x80)) return; /* reverse video (lower-left pixel) inverts all the other pixels */ if (attr & AT_REVERSE) attr ^= 0x7f; /* get the bit mask for the pixel */ bits = attr_bits[y % 4][x % 2]; /* set it ? */ if (set) attr |= bits; else attr &= ~ bits; /* reverse video (lower-left pixel) inverts all the other pixels */ if (attr & AT_REVERSE) attr ^= 0x7f; terminal_putchar(kaypro_terminal, cx, cy, attr); }
static wchar_t get_next_wchar(editor_t *editor) { const char *buffer = NULL; size_t bytes = 0; char utf8_buffer[8] = { '\0' }; int ch = terminal_getchar(); editor->input_buffer[(int) editor->pending_bytes++] = ch; if (terminal_is_utf8()) { buffer = editor->input_buffer; bytes = editor->pending_bytes; } else { if (editor->pending_bytes > 1) { convert(CONVERT_G2U, editor->input_buffer, editor->pending_bytes, utf8_buffer, sizeof(utf8_buffer), NULL, NULL); editor->pending_bytes = 0; if (utf8_buffer[0] != '\0') { buffer = utf8_buffer; bytes = strlen(utf8_buffer); } } else if (!(ch & 0x80)) { editor->pending_bytes = 0; return ch; } } if (buffer) { wchar_t wc = next_wchar(&buffer, &bytes); if ((wc && wc != WEOF) || editor->pending_bytes == sizeof(editor->input_buffer)) { editor->pending_bytes = 0; return wc; } } return 0; }
static void user_login(void) { char fname[STRLEN]; // SYSOP gets all permission bits when login. if (strcmp(currentuser.userid, "SYSOP") == 0) { currentuser.userlevel = ~0; substitut_record(PASSFILE, ¤tuser, sizeof(currentuser), usernum); } fromhost[sizeof(fromhost) - 1] = 0; //added by iamfat 2004.01.05 to avoid overflow log_usies("ENTER", fromhost, ¤tuser); SpecialID(currentuser.userid, fromhost, sizeof(fromhost)); u_enter(); report("Enter", currentuser.userid); #ifdef USE_NOTEPAD notepad_init(); if (strcmp(currentuser.userid, "guest") != 0) { if (DEFINE(DEF_NOTEPAD)) { int noteln; if (lastnote> currentuser.notedate) currentuser.noteline = 0; noteln = countln("etc/notepad"); if (currentuser.noteline == 0) { shownotepad(); } else if ((noteln - currentuser.noteline)> 0) { screen_move(0, 0); ansimore2("etc/notepad", NA, 0, noteln - currentuser.noteline + 1); terminal_getchar(); screen_clear(); } currentuser.noteline = noteln; write_defnotepad(); } } #endif if (show_statshm("etc/hotspot", 0)) { screen_flush(); pressanykey(); } if ((vote_flag(NULL, '\0', 2 /* 检查读过新的Welcome 没 */) == 0)) { if (dashf("Welcome")) { ansimore("Welcome", YEA); vote_flag(NULL, 'R', 2 /* 写入读过新的Welcome */); } } else { ansimore("Welcome2", YEA); } show_statshm("0Announce/bbslist/day", 1); screen_flush(); screen_move_clear(-2); if (currentuser.numlogins < 1) { currentuser.numlogins = 0; //% prints("\033[1;36m☆ 这是您第 \033[33m1\033[36m 次拜访本站,请记住今天吧。\n"); prints("\033[1;36m\xa1\xee \xd5\xe2\xca\xc7\xc4\xfa\xb5\xda \033[33m1\033[36m \xb4\xce\xb0\xdd\xb7\xc3\xb1\xbe\xd5\xbe\xa3\xac\xc7\xeb\xbc\xc7\xd7\xa1\xbd\xf1\xcc\xec\xb0\xc9\xa1\xa3\n"); //% prints("☆ 您第一次连入本站的时间为 \033[33m%s\033[m ", format_time(time(NULL), TIME_FORMAT_ZH)); prints("\xa1\xee \xc4\xfa\xb5\xda\xd2\xbb\xb4\xce\xc1\xac\xc8\xeb\xb1\xbe\xd5\xbe\xb5\xc4\xca\xb1\xbc\xe4\xce\xaa \033[33m%s\033[m ", format_time(fb_time(), TIME_FORMAT_ZH)); } else { prints( //% "\033[1;36m☆ 这是您第 \033[33m%d\033[36m 次拜访本站,上次您是从 \033[33m%s\033[36m 连往本站。\n", "\033[1;36m\xa1\xee \xd5\xe2\xca\xc7\xc4\xfa\xb5\xda \033[33m%d\033[36m \xb4\xce\xb0\xdd\xb7\xc3\xb1\xbe\xd5\xbe\xa3\xac\xc9\xcf\xb4\xce\xc4\xfa\xca\xc7\xb4\xd3 \033[33m%s\033[36m \xc1\xac\xcd\xf9\xb1\xbe\xd5\xbe\xa1\xa3\n", currentuser.numlogins + 1, currentuser.lasthost); //% prints("☆ 上次连线时间为 \033[33m%s\033[m ", format_time(currentuser.lastlogin, TIME_FORMAT_ZH)); prints("\xa1\xee \xc9\xcf\xb4\xce\xc1\xac\xcf\xdf\xca\xb1\xbc\xe4\xce\xaa \033[33m%s\033[m ", format_time(currentuser.lastlogin, TIME_FORMAT_ZH)); } terminal_getchar(); setuserfile(fname, BADLOGINFILE); if (ansimore(fname, NA) != -1) { //% if (askyn("您要删除以上密码输入错误的记录吗", NA, NA) == YEA) if (askyn("\xc4\xfa\xd2\xaa\xc9\xbe\xb3\xfd\xd2\xd4\xc9\xcf\xc3\xdc\xc2\xeb\xca\xe4\xc8\xeb\xb4\xed\xce\xf3\xb5\xc4\xbc\xc7\xc2\xbc\xc2\xf0", NA, NA) == YEA) unlink(fname); } set_safe_record(); tui_check_uinfo(¤tuser); strlcpy(currentuser.lasthost, fromhost, sizeof(currentuser.lasthost)); if (login_start_time - currentuser.lastlogin >= 20 * 60 || !strcmp(currentuser.userid, "guest") || currentuser.numlogins < 100) { currentuser.numlogins++; } session_basic_info_t *res = get_my_sessions(); update_user_stay(¤tuser, true, session_basic_info_count(res) > 1); session_basic_info_clear(res); #ifdef ALLOWGAME if (currentuser.money> 1000000) { currentuser.nummedals += currentuser.money / 10000; currentuser.money %= 1000000; } if ((signed int) (currentuser.money - currentuser.bet) < -4990 && currentuser.numlogins < 10 && currentuser.numposts < 10 && currentuser.nummedals == 0) currentuser.money += 1000; #endif if (currentuser.firstlogin == 0) { currentuser.firstlogin = time(NULL) - 7 * 86400; } substitut_record(PASSFILE, ¤tuser, sizeof(currentuser), usernum); extern char currmaildir[]; setmdir(currmaildir, currentuser.userid); check_register_info(); }
int multi_getdata(int line, int col, int maxcol, const char *prompt, char *buf, int len, int maxline, int clearlabel, int textmode) { extern int RMSG; extern int msg_num; int ch, x, y, startx, starty, curr, i, k, chk, cursorx, cursory, size; bool init = true; char tmp[MAX_MSG_SIZE+1]; if (clearlabel == YEA) memset(buf, 0, len); screen_move(line, col); if (prompt) prints("%s", prompt); screen_coordinates(&starty, &startx); curr = strlen(buf); strncpy(tmp, buf, MAX_MSG_SIZE); tmp[MAX_MSG_SIZE] = 0; cursory = starty; cursorx = startx; while (true) { y = starty; x = startx; screen_move(y, x); chk = 0; if (curr == 0) { cursory = y; cursorx = x; } //以下遍历buf的功能是显示出每次terminal_getchar的动作。 size = strlen(buf); for (i = 0; i < size; i++) { if (chk) { chk = 0; } else { if (buf[i] < 0) chk=1; } if (chk && x >= maxcol) x++; if (buf[i] != '\r' && buf[i] != '\n') { if (x > maxcol) { clrtoeol(); x = 0; y++; screen_move(y, x); } //Ctrl('H')中退行bug if (x == maxcol && y - starty + 1 < MAX_MSG_LINE) { screen_move(y + 1, 0); clrtoeol(); screen_move(y, x); } if (init) prints("\033[4m"); prints("%c", buf[i]); x++; } else { clrtoeol(); x = 0; y++; screen_move(y, x); } if(i == curr - 1) { //打印到buf最后一个字符时的x和y是下一步初始xy cursory = y; cursorx = x; } } clrtoeol(); screen_move(cursory, cursorx); ch = terminal_getchar(); if ((RMSG == YEA) && msg_num == 0) { if (ch == Ctrl('Z') ) { buf[0] = Ctrl('Z'); x = 1; break; //可以改成return 某个行试试 } if (ch == Ctrl('A') ) { buf[0] = Ctrl('A'); x = 1; break; } } if(ch == Ctrl('Q')) { init = true; buf[0]=0; curr=0; for(k=0; k < MAX_MSG_LINE;k++) { screen_move(starty+k,0); clrtoeol(); } continue; } if(textmode == 0){ if ((ch == '\n' || ch == '\r')) break; } else{ if (ch == Ctrl('W')) break; } switch(ch) { case KEY_UP: init = false; if (cursory > starty) { y = starty; x = startx; chk = 0; if(y == cursory - 1 && x <= cursorx) curr = 0; size = strlen(buf); for (i = 0; i < size; i++) { if (chk) { chk = 0; } else { if (buf[i] < 0) chk = 1; } if (chk && x >= maxcol) x++; if (buf[i] != '\r' && buf[i] != '\n') { if(x > maxcol) { x = col; y++; } x++; } else { x = col; y++; } if (y == cursory - 1 && x <= cursorx) curr = i + 1; } } break; case KEY_DOWN: init=false; if(cursory<y) { y = starty; x = startx; chk = 0; if(y==cursory+1&&x<=cursorx) curr=0; size = strlen(buf); for(i=0; i<size; i++) { if(chk) chk=0; else if(buf[i]<0) chk=1; if(chk&&x>=maxcol) x++; if(buf[i]!=13&&buf[i]!=10) { if(x>maxcol) { x = col; y++; } x++; } else { x = col; y++; } if(y==cursory+1&&x<=cursorx) curr=i+1; } } break; case '\177': case Ctrl('H'): if(init) { init=false; buf[0]=0; curr=0; } if(curr>0) { int currDec = 0, patch = 0; if(buf[curr-1] < 0){ for(i = curr - 2; i >=0 && buf[i]<0; i--) patch++; if(patch%2 == 0 && buf[curr] < 0) patch = 1; else if(patch%2) patch = currDec = 1; else patch = 0; } if(currDec) curr--; strcpy(tmp, &buf[curr+patch]); buf[--curr] = 0; strcat(buf, tmp); } break; case KEY_DEL: if (init) { init = false; buf[0] = '\0'; curr = 0; } size = strlen(buf); if (curr < size) memmove(buf + curr, buf + curr + 1, size - curr); break; case KEY_LEFT: init=false; if(curr>0) { curr--; } break; case KEY_RIGHT: init=false; if(curr<strlen(buf)) { curr++; } break; case KEY_HOME: case Ctrl('A'): init=false; curr--; while (curr >= 0 && buf[curr] != '\n' && buf[curr] != '\r') curr--; curr++; break; case KEY_END: case Ctrl('E'): init = false; size = strlen(buf); while (curr < size && buf[curr] != '\n' && buf[curr] != '\r') curr++; break; case KEY_PGUP: init=false; curr=0; break; case KEY_PGDN: init=false; curr = strlen(buf); break; default: if(isprint2(ch)&&strlen(buf)<len-1) { if(init) { init=false; buf[0]=0; curr=0; } size = strlen(buf); memmove(buf + curr + 1, buf + curr, size - curr + 1); size++; buf[curr++]=ch; y = starty; x = startx; chk = 0; for(i = 0; i < size; i++) { if(chk) chk=0; else if(buf[i]<0) chk=1; if(chk&&x>=maxcol) x++; if(buf[i]!=13&&buf[i]!=10) { if(x>maxcol) { x = col; y++; } x++; } else { x = col; y++; } } //采用先插入后检查是否超过maxline,如果超过,那么删去这个字符调整 if (y - starty + 1 > maxline) { memmove(buf + curr -1, buf + curr, size - curr + 1); curr--; } } init=false; break; } } return y-starty+1; }
static int _tui_input(int line, int col, const char *prompt, char *buf, int len, int echo, int clear, bool utf8) { extern int RMSG; extern int msg_num; if (clear) buf[0] = '\0'; buf[len - 1] = '\0'; int real_x = prompt ? screen_display_width(prompt, utf8) : 0; int cur, clen; cur = clen = strlen(buf); bool inited = screen_inited(), prompted = false; while (1) { if (inited || !prompted) { screen_move(line, col); clrtoeol(); if (prompt) { if (utf8) screen_printf("%s", prompt); else prints("%s", prompt); } prompted = true; } if (inited) { if (echo) prints("%s", buf); else tui_repeat_char('*', clen); screen_move(line, real_x + cur); } if (RMSG) screen_flush(); int ch = terminal_getchar(); if (RMSG && msg_num == 0) { if (ch == Ctrl('Z') || ch == KEY_UP) { buf[0] = Ctrl('Z'); clen = 1; break; } if (ch == Ctrl('A') || ch == KEY_DOWN) { buf[0] = Ctrl('A'); clen = 1; break; } } if (ch == '\n' || ch == '\r') break; if (!inited) { if (ch == '\x7f' || ch == Ctrl('H')) { int dec = remove_character(buf, &cur, clen, true); if (dec) { clen -= dec; screen_puts("\x8 \x8", 3); } } else if (isprint2(ch) && clen < len - 1) { buf[cur] = ch; buf[++cur] = '\0'; ++clen; screen_putc(echo ? ch : '*'); } continue; } if (ch == '\x7f' || ch == Ctrl('H')) { clen -= remove_character(buf, &cur, clen, true); } else if (ch == KEY_DEL) { clen -= remove_character(buf, &cur, clen, false); } else if (ch == KEY_LEFT) { if (cur > 0) --cur; } else if (ch == KEY_RIGHT) { if (cur < clen) ++cur; } else if (ch == Ctrl('E') || ch == KEY_END) { cur = clen; } else if (ch == Ctrl('A') || ch == KEY_HOME) { cur = 0; } else if (isprint2(ch) && clen < len - 1) { if (buf[cur] != '\0') memmove(buf + cur + 1, buf + cur, clen - cur); buf[cur++] = ch; buf[++clen] = '\0'; } } screen_putc('\n'); screen_flush(); return clen; }
int usercomplete(char *prompt, char *data) { char *cwbuf, *cwlist, *temp; int cwnum, x, y, origx, origy; int clearbot = NA, count = 0, morenum = 0; char ch; cwbuf = malloc(MAXUSERS * (IDLEN + 1)); if (prompt != NULL) { prints("%s", prompt); clrtoeol(); } temp = data; cwlist = u_namearray((void *)cwbuf, &cwnum, ""); screen_coordinates(&y, &x); screen_coordinates(&origy, &origx); while ((ch = terminal_getchar()) != EOF) { if (ch == '\n' || ch == '\r') { int i; char *ptr; *temp = '\0'; prints("\n"); ptr = cwlist; for (i = 0; i < cwnum; i++) { if (strncasecmp(data, ptr, IDLEN + 1) == 0) strcpy(data, ptr); ptr += IDLEN + 1; } /* if( cwnum == 1 ) strcpy( data, cwlist ); */ break; } // if if (ch == ' ' || ch == KEY_TAB) { int col, len, i, j; int n; if (cwnum == 1) { strcpy(data, cwlist); screen_move(y, x); prints("%s", data + count); count = strlen(data); temp = data + count; screen_coordinates(&y, &x); continue; } for (i = strlen(data); i && i < IDLEN; i++) { ch = cwlist[i]; if (ch == '\0') break; for (j = 0; j < cwnum; j++) { if (toupper((cwlist + (IDLEN + 1) * j)[i]) != toupper(ch)) break; } if (j != cwnum) break; *temp++ = ch; *temp = '\0'; n = UserSubArray((void *)cwbuf, (void *)cwlist, cwnum, ch, count); if (n == 0) { temp--; *temp = '\0'; break; } cwlist = cwbuf; count++; cwnum = n; morenum = 0; screen_move(y, x); outc(ch); x++; } clearbot = YEA; col = 0; len = UserMaxLen((void *)cwlist, cwnum, morenum, NUMLINES); screen_move(origy + 1, 0); screen_clrtobot(); //% printdash(" 所有使用者列表 "); printdash(" \xcb\xf9\xd3\xd0\xca\xb9\xd3\xc3\xd5\xdf\xc1\xd0\xb1\xed "); while (len + col < 79) { int i; for (i = 0; morenum < cwnum && i < NUMLINES - origy + 1; i++) { char *tmpptr = cwlist + (IDLEN + 1) * morenum++; if (*tmpptr != '\0') { //by Eric screen_move(origy + 2 + i, col); prints("%s ", tmpptr); } else i--; } col += len + 2; if (morenum >= cwnum) break; len = UserMaxLen((void *)cwlist, cwnum, morenum, NUMLINES); } if (morenum < cwnum) { screen_move(-1, 0); //% prints("[1;44m-- 还有使用者 -- [m"); prints("[1;44m-- \xbb\xb9\xd3\xd0\xca\xb9\xd3\xc3\xd5\xdf -- [m"); } else { morenum = 0; } screen_move(y, x); continue; } if (ch == '\177' || ch == '\010') { if (temp == data) continue; temp--; count--; *temp = '\0'; cwlist = u_namearray((void *)cwbuf, &cwnum, data); morenum = 0; x--; screen_move(y, x); outc(' '); screen_move(y, x); continue; } if (count < STRLEN) { int n; *temp++ = ch; *temp = '\0'; n = UserSubArray((void *)cwbuf, (void *)cwlist, cwnum, ch, count); if (n == 0) { temp--; *temp = '\0'; continue; } cwlist = cwbuf; count++; cwnum = n; morenum = 0; screen_move(y, x); outc(ch); x++; } } free(cwbuf); if (ch == EOF) longjmp(byebye, -1); prints("\n"); screen_flush(); if (clearbot) { screen_move(origy, 0); screen_clrtobot(); } if (*data) { screen_move(origy, origx); prints("%s\n", data); } return 0; }
int namecomplete(char *prompt, char *data) { char *temp; int ch; int count = 0; int clearbot = NA; struct word *cwlist, *morelist; int x, y; int origx, origy; if (prompt != NULL) { prints("%s", prompt); clrtoeol(); } temp = data; if (toplev == NULL) AddNameList(""); cwlist = GetSubList("", toplev); morelist = NULL; screen_coordinates(&y, &x); screen_coordinates(&origy, &origx); while ((ch = terminal_getchar()) != EOF) { if (ch == '\n' || ch == '\r') { *temp = '\0'; prints("\n"); if (NumInList(cwlist) == 1) strcpy(data, cwlist->name); else { /* 版面 ID 选择的一个精确匹配问题 period */ struct word *list; for (list = cwlist; list != NULL; list = list->next) { if (!strcasecmp(data, list->name)) { strcpy(data, list->name); break; } //if } //for } //else ClearSubList(cwlist); break; } if (ch == ' ' || ch == KEY_TAB) { int col, len, i; if (NumInList(cwlist) == 1) { strcpy(data, cwlist->name); screen_move(y, x); prints("%s", data + count); count = strlen(data); temp = data + count; screen_coordinates(&y, &x); continue; } for (i = strlen(data); i && i < STRLEN; i++) { struct word *node; ch = cwlist->name[i]; if (ch == '\0') break; for (node = cwlist; node; node = node->next) { if (toupper(ch) != toupper(node->name[i])) break; } if (node != NULL) break; *temp++ = ch; count++; *temp = '\0'; node = GetSubList(data, cwlist); if (node == NULL) { temp--; *temp = '\0'; count--; break; } ClearSubList(cwlist); cwlist = node; morelist = NULL; screen_move(y, x); outc(ch); x++; } //for clearbot = YEA; col = 0; if (!morelist) morelist = cwlist; len = MaxLen(morelist, NUMLINES); screen_move(origy + 1, 0); screen_clrtobot(); prints(ANSI_CMD_SO); //% printdash(" 列表 "); printdash(" \xc1\xd0\xb1\xed "); prints(ANSI_CMD_SE); while (len + col < 80) { int i; for (i = NUMLINES; (morelist) && (i > origy - 1); i--) { if (morelist->name[0] != '\0') { screen_move(origy + 2 + (NUMLINES - i), col); prints("%s", morelist->name); } else { i++; } morelist = morelist->next; } col += len + 2; if (!morelist) break; len = MaxLen(morelist, NUMLINES); } //while if (morelist) { screen_move(-1, 0); //% prints("[1;44m-- 还有 -- [m"); prints("[1;44m-- \xbb\xb9\xd3\xd0 -- [m"); } screen_move(y, x); continue; } if (ch == '\177' || ch == '\010') { if (temp == data) continue; temp--; count--; *temp = '\0'; ClearSubList(cwlist); cwlist = GetSubList(data, toplev); morelist = NULL; x--; screen_move(y, x); outc(' '); screen_move(y, x); continue; } //if if (count < STRLEN) { struct word *node; *temp++ = ch; count++; *temp = '\0'; node = GetSubList(data, cwlist); if (node == NULL) { temp--; *temp = '\0'; count--; continue; } ClearSubList(cwlist); cwlist = node; morelist = NULL; screen_move(y, x); outc(ch); x++; } } // while if (ch == EOF) longjmp(byebye, -1); prints("\n"); screen_flush(); if (clearbot) { screen_move(origy, 0); screen_clrtobot(); } if (*data) { screen_move(origy, origx); prints("%s\n", data); /* for (x=1; x<500; x++); delay */ } return 0; }
int menu_get_input (void) { int cx, cy; int option = 0; int prev_option = 1; int x, y; int KeyPressed; struct termios stored_terminal; struct get_arrow_keys num_keypad = { '8', '2', '4', '6' }; struct get_arrow_keys alpha_keypad = { 'j', 'm', ',', '.' }; get_term_settings (stored_terminal); set_term_raw (); /* Paint the screen with the bitmap */ put_screen (menu_picture); /* Put the buttons on the screen */ for (cx = 0; cx <= MAX_MENU_COLS-1; cx++) for (cy = 0; cy <= MAX_MENU_ROWS-1; cy++) { x = MENU_COL+MENU_COL_GAP*cx; y = MENU_ROW+MENU_ROW_GAP*cy; ansi_PutString (x+1, y+1, menu_options [cy*MAX_MENU_COLS+cx]); draw_box_XY (x, y, x+MENU_ITEM_WIDTH, y+MENU_ITEM_HEIGHT, CHAR_hyphen, CHAR_pipe, CHAR_plus); } /* Keep looping until 'select' or 'Q' has been pressed and then return the option selected to the parent function */ while (1) { if (prev_option != option) { cx = prev_option % 2; cy = prev_option / 2; ansi_DefaultAttr (); x = MENU_COL+MENU_COL_GAP*cx; y = MENU_ROW+MENU_ROW_GAP*cy; ansi_PutString (x+1, y+1, menu_options [cy*MAX_MENU_COLS+cx]); draw_box_XY (x, y, x+MENU_ITEM_WIDTH, y+MENU_ITEM_HEIGHT, CHAR_hyphen, CHAR_pipe, CHAR_plus); cx = option % 2; cy = option / 2; ansi_SetAttr (ATTR_reverse); x = MENU_COL+MENU_COL_GAP*cx; y = MENU_ROW+MENU_ROW_GAP*cy; ansi_PutString (x+1, y+1, menu_options [cy*MAX_MENU_COLS+cx]); draw_box_XY (x, y, x+MENU_ITEM_WIDTH, y+MENU_ITEM_HEIGHT, CHAR_hyphen, CHAR_pipe, CHAR_plus); ansi_SetAttr (ATTR_normal); } prev_option = option; wait_for_keypress (); switch (get_arrow (TRUE, &alpha_keypad, &num_keypad)) { case DIR_up: if ((option != 0) && (option != 1)) option-=2; break; case DIR_down: if ((option != 4) && (option != 5)) option+=2; break; case DIR_left: if (option % 2 == 1) option--; break; case DIR_right: if (option % 2 == 0) option++; break; case DIR_unknown: KeyPressed = terminal_getchar (); if ((KeyPressed == MENU_SELECT_1) || (KeyPressed == MENU_SELECT_2) || (KeyPressed == MENU_SELECT_3)) { set_term_settings (stored_terminal); return (option); } if (toupper (KeyPressed) == 'Q') { set_term_settings (stored_terminal); return (5); } break; } } }
int play_level (int level, long int *score, int lives, int total_score) { int aircraft_x = 2, prev_aircraft_x = aircraft_x; float aircraft_y_float = 8.0; int aircraft_y = aircraft_y_float, prev_aircraft_y = aircraft_y; int direction = DIR_FORWARD; int aircraft_stats; int x_offset = 0; float y_offset = 0.0; char KeyPressed = 0; struct timeval start_time, end_time; struct timezone start_timezone, end_timezone; long int bonus = 0; struct termios stored_terminal; struct get_arrow_keys num_keypad = { '8', '2', '4', '6' }; struct get_arrow_keys alpha_keypad = { 0, 0, ',', '.' }; get_term_settings (stored_terminal); set_term (0, 0); draw_frame (); put_screen (level_data [level].map); ansi_Position (2, MAX_SCR_ROWS); ansi_SetAttr (ATTR_reverse); ansi_printf (" Game Info - Score: [%6d] Lives Remaining: [%2d] Current Level: [%2d]", total_score, lives, level); ansi_SetAttr (ATTR_normal); park_cursor (); ansi_fflush (); sleep (WAIT_FOR_UPDATE); /* Really slow terminals need a few seconds to catch up */ start_time (); put_plane (aircraft_x, aircraft_y, aircraft); do { aircraft_x += x_offset; aircraft_y_float += y_offset; aircraft_y = aircraft_y_float; move_picture (prev_aircraft_x, prev_aircraft_y, aircraft_x, aircraft_y, MAX_SCR_PLANE_X, MAX_SCR_PLANE_Y, aircraft, MAX_SCR_COLS, MAX_SCR_ROWS, level_data [level].map); prev_aircraft_x = aircraft_x; prev_aircraft_y = aircraft_y; if (delay_for_key (WAIT_TIME_Sec, WAIT_TIME_uSec)) switch (get_arrow (TRUE, &num_keypad, &alpha_keypad)) { case DIR_left: direction = DIR_BACKWARD; break; case DIR_right: direction = DIR_FORWARD; break; default: KeyPressed = terminal_getchar (); break; } aircraft_stats = check_aircraft (aircraft_x, aircraft_y, level, aircraft); /* Check to see if any 'events' have happened */ if (aircraft_stats != OBJ_NOTHING) { if ((aircraft_stats & OBJ_COLLISION) == OBJ_COLLISION) { set_term_settings (stored_terminal); return (MSG_COLLISION); } if ((aircraft_stats & OBJ_FIRE) == OBJ_FIRE) { set_term_settings (stored_terminal); return (MSG_FIRE); } if ((aircraft_stats & OBJ_WATER) == OBJ_WATER) { set_term_settings (stored_terminal); return (MSG_WATER); } if ((aircraft_stats & OBJ_FLOOR) == OBJ_FLOOR) { set_term_settings (stored_terminal); return (MSG_FLOOR); } if ((aircraft_stats & OBJ_RIGHTWALL) == OBJ_RIGHTWALL) { end_time (); *score = calculate_score (diff_time (), bonus, level); set_term_settings (stored_terminal); return (MSG_WINLEVEL); } if ((aircraft_stats & OBJ_WINGAME) == OBJ_WINGAME) { end_time (); *score = calculate_score (diff_time (), bonus, level); set_term_settings (stored_terminal); return (MSG_WINGAME); } } if ((aircraft_stats & OBJ_BONUS) == OBJ_BONUS) bonus++; /* Ok, the Glider has not crashed and the level has not ended, we must now move it appropriately */ x_offset = direction; y_offset = STEP_DOWN; if ((aircraft_stats & OBJ_VENT) == OBJ_VENT) y_offset = STEP_VENT; if ((aircraft_stats & OBJ_ROOF) == OBJ_ROOF) if ((aircraft_stats & OBJ_VENT) == OBJ_VENT) y_offset = 0.0; if ((aircraft_stats & OBJ_LEFTWALL) == OBJ_LEFTWALL) if (direction == DIR_BACKWARD) x_offset = 0; } while (toupper (KeyPressed) != 'Q'); set_term_settings (stored_terminal); return (MSG_QUIT); }