void write_admin_menu(int shift) { int i; // The options available const char *options[] = { "1. Restock", "2. Enroll", "3. Deal Drugs", "0. Exit" }; const int num_options = 4; // Should be the number of things in the above // Don't let us shift more than the number of options if (shift > num_options) { return; } // Whealer's fault. Shift options around in a circle admin_line += shift + num_options; admin_line %= num_options; // Clean up clear_screen(); cursor_blink_off(); cursor_off(); // Write the first thing write_string(options[admin_line]); // Write the next thing - go around in a circle. Also Whealer's fault write_string("\n"); write_string(options[(admin_line + 1) % num_options]); }
int main() { char insert_key; clrscr(); Outside_Box(); Inside_Box(); cursor_off(); while(1) { press_key = getch(); insert_key = check_key_value(press_key); switch(insert_key) { case F10: move_inverse(); break; case F1: print_string(9, 9, "Help", 7); break; case ALTL: print_string(9, 9, "Load", 7); break; case ALTS: print_string(9, 9, "Save", 7); break; case ALTA: print_string(9, 9, "Save as", 7); break; case ALTX: return 0; } } }
void message(char *s) { cursor_off(); clear_screen(); cursor(10, 10); printf("%s", s); getch(); cursor_on(); }
void LCDi2cR::init () { I2c.begin(); on(); clear(); blink_off(); cursor_off(); home(); }
bool LCDi2cNHD::init () { Wire.begin(); // TODO: Check that LCD was initialized properly. on() should return a value, command() should return a value and check endTranmission value, a global flag (initializeError) should be added if ( !on() ) { return false; // error } clear(); blink_off(); cursor_off(); home(); return true; // success }
//print the matrix void print_matrix(void){ char p,l; fill(); cursor_off(); print_hits(); l = 20-(players<<1); print_num(level,2,36,l); for (p=0;p<players+1;++p){ l += 2; print_num(score[p],6,28,l); } stop = 1; display_time(); appear(); cursor_on(); delay(230); }
static void xorcursor() { static byte store_x,store_lh; static unsigned store_lhb; static byte state=0; extern byte display_x; store_x=display_x; store_lh=line_height; store_lhb=line_height_bytes; display_x=x; cursor_y=y1; line_height=ozgetfontheight(ozgetfont()); line_height_bytes=30*line_height; if(state^=1) do_cursor_on(); else cursor_off(); display_x=store_x; line_height=store_lh; line_height_bytes=store_lhb; }
void tty_putc(uint8_t minor, unsigned char c) { irqflags_t irq; if (minor == 3) tr1865_rxtx = c; else { irq = di(); if (curtty != minor -1) { /* Kill the cursor as we are changing the memory buffers. If we don't do this the next cursor_off will hit the wrong buffer */ cursor_off(); vt_save(&ttysave[curtty]); curtty = minor - 1; vt_load(&ttysave[curtty]); /* Fix up the cursor */ cursor_on(ttysave[curtty].cursory, ttysave[curtty].cursorx); } vtoutput(&c, 1); irqrestore(irq); } }
void vtexchange(void) { /* Swap the pointers over: TRS80 video we switch by copying not flipping hardware pointers */ uint8_t *v = vtbase[0]; vtbase[0] = vtbase[1]; vtbase[1] = v; /* The cursor x/y for current tty are stale in the save area so save them */ vt_save(&ttysave[curtty]); /* Before we flip the memory */ cursor_off(); /* Swap the buffers over */ __asm ld hl, #0xf800 ld de, #_vtbackbuf ld bc, #VT_WIDTH*VT_HEIGHT exchit: push bc ld a, (de) ; Could be optimised but its only 2K ld c, (hl) ; Probably worth doing eventuallly ex de, hl ld (hl), c ld (de), a inc hl inc de pop bc dec bc ld a, b or c jr nz, exchit ret __endasm; /* Cursor back */ cursor_on(ttysave[inputtty].cursory, ttysave[inputtty].cursorx); }
/* VT52 alike functionality */ void vtoutput(unsigned char *p, unsigned int len) { irqflags_t irq; uint8_t cq; /* We can get re-entry into the vt code from tty echo. This is one of the few places in Fuzix interrupts bite us this way. If we have a clash then we queue the echoed symbol and print it in the thread of execution it interrupted. We only queue one so in theory might lose the odd echo - but the same occurs with real uarts. If anyone actually has printing code slow enough this is a problem then vtpend can turn into a small queue */ irq = di(); if (vtbusy) { vtpend = *p; irqrestore(irq); return; } vtbusy = 1; irqrestore(irq); cursor_off(); do { while (len--) { unsigned char c = *p++; if (vtmode == 0) { charout(c); continue; } if (vtmode == 1) { vtmode = escout(c); continue; } if (vtmode == 2) { ncursory = c - ' '; vtmode++; continue; } else if (vtmode == 3) { int ncursorx = c - ' '; if (ncursory >= 0 && ncursorx <= VT_BOTTOM) cursory = ncursory; if (ncursorx >= 0 && ncursorx <= VT_RIGHT) cursorx = ncursorx; vtmode = 0; } else { vtattr = c; vtmode = 0; continue; } } /* Copy the pending symbol and clear the buffer */ cq = vtpend; vtpend = 0; /* Any loops print the single byte in cq */ p = &cq; len = 1; /* Until we don't get interrupted */ } while(cq); cursor_on(cursory, cursorx); vtbusy = 0; }
int intake(struct world *mzx_world, char *string, int max_len, int x, int y, char color, int exit_type, int filter_type, int *return_x_pos, bool robo_intk, char *macro) { int currx, curr_len, macro_position = -1; int done = 0, place = 0; char cur_char = 0; char temp_char; int in_macro; int use_mask = mzx_world->conf.mask_midchars; int mouse_press; int key; if(macro != NULL) macro_position = 0; // Activate cursor if(insert_on) cursor_underline(); else cursor_solid(); // Put cursor at the end of the string... currx = curr_len = (int)strlen(string); // ...unless return_x_pos says not to. if((return_x_pos) && (*return_x_pos < currx)) currx = *return_x_pos; if(robo_intk && (currx > 75)) move_cursor(77, y); else move_cursor(x + currx, y); if(insert_on) cursor_underline(); else cursor_solid(); do { if(!robo_intk) { if(use_mask) write_string_mask(string, x, y, color, 0); else write_string_ext(string, x, y, color, 0, 0, 16); } else { draw_char('\x11', color, 79, y); if((curr_len < 76) || (currx < 76)) { draw_char('\x10', color, 0, y); if(curr_len < 76) { if(use_mask) write_line_mask(string, x, y, color, 0); else write_line_ext(string, x, y, color, 0, 0, 16); fill_line(76 - curr_len, x + curr_len, y, 32, color); } else { temp_char = string[76]; string[76] = 0; if(use_mask) write_line_mask(string, x, y, color, 0); else write_line_ext(string, x, y, color, 0, 0, 16); string[76] = temp_char; draw_char('\xaf', color, 79, y); } } else { draw_char('\x20', color, 77, y); if(strlen(string + currx - 75) > 78) { temp_char = string[currx + 1]; string[currx + 1] = 0; if(use_mask) { write_line_mask(string + currx - 75, x, y, color, 0); } else { write_line_ext(string + currx - 75, x, y, color, 0, 0, 16); } string[currx + 1] = temp_char; } else { if(use_mask) { write_line_mask(string + currx - 75, x, y, color, 0); } else { write_line_ext(string + currx - 75, x, y, color, 0, 0, 16); } } draw_char('\xae', color, 0, y); if(currx < curr_len) draw_char('\xaf', color, 79, y); } draw_char('\x20', color, 78, y); } if(!robo_intk) { fill_line(max_len + 1 - curr_len, x + curr_len, y, 32, color); } else { write_number(currx + 1, 79, 32, 0, 3, 0, 10); write_number(curr_len + 1, 79, 36, 0, 3, 0, 10); } in_macro = 0; // Get key if(macro_position != -1) { key = macro[macro_position]; cur_char = key; macro_position++; if(macro[macro_position] == 0) macro_position = -1; if(key == '^') key = IKEY_RETURN; } else { update_screen(); update_event_status_delay(); key = get_key(keycode_internal); place = 0; cur_char = get_key(keycode_unicode); } mouse_press = get_mouse_press_ext(); if(get_mouse_press_ext()) { int mouse_x, mouse_y; get_mouse_position(&mouse_x, &mouse_y); if((mouse_y == y) && (mouse_x >= x) && (mouse_x <= (x + max_len)) && (mouse_press <= MOUSE_BUTTON_RIGHT)) { // Yep, reposition cursor. currx = mouse_x - x; if(currx > curr_len) currx = curr_len; } else { key = -1; done = 1; } } // Handle key cases switch(key) { case IKEY_ESCAPE: { // ESC if(exit_type > 0) { done = 1; } break; } case IKEY_RETURN: { // Enter done = 1; break; } case IKEY_HOME: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { // Home currx = 0; } break; } case IKEY_END: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { // End currx = curr_len; } break; } case IKEY_LEFT: { if(get_ctrl_status(keycode_internal)) { // Find nearest space to the left if(currx) { char *current_position = string + currx; if(currx) current_position--; if(!isalnum((int)*current_position)) { while(currx && !isalnum((int)*current_position)) { current_position--; currx--; } } do { current_position--; currx--; } while(currx && isalnum((int)*current_position)); if(currx < 0) currx = 0; } } else { // Left if(currx > 0) currx--; } break; } case IKEY_RIGHT: { if(get_ctrl_status(keycode_internal)) { // Find nearest space to the right if(currx < curr_len) { char *current_position = string + currx; char current_char = *current_position; if(!isalnum((int)current_char)) { do { current_position++; currx++; current_char = *current_position; } while(current_char && !isalnum((int)current_char)); } while(current_char && isalnum((int)current_char)) { current_position++; currx++; current_char = *current_position; } } } else { // Right if(currx < curr_len) currx++; } break; } case IKEY_F1: case IKEY_F2: case IKEY_F3: case IKEY_F4: case IKEY_F5: case IKEY_F6: case IKEY_F7: case IKEY_F8: case IKEY_F9: case IKEY_F10: case IKEY_F11: case IKEY_F12: case IKEY_UP: case IKEY_DOWN: case IKEY_TAB: case IKEY_PAGEUP: case IKEY_PAGEDOWN: { done = 1; break; } case IKEY_INSERT: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { // Insert if(insert_on) cursor_solid(); else cursor_underline(); insert_on ^= 1; } break; } case IKEY_BACKSPACE: { // Backspace, at 0 it might exit if(get_alt_status(keycode_internal)) { // Alt-backspace, erase input curr_len = currx = 0; string[0] = 0; } else if(get_ctrl_status(keycode_internal)) { // Find nearest space to the left if(currx) { int old_position = currx; if(!isalnum((int)string[currx])) { while(currx && !isalnum((int)string[currx])) { currx--; } } while(currx && isalnum((int)string[currx])) { currx--; } curr_len -= old_position - currx; memmove(string + currx, string + old_position, strlen(string + old_position) + 1); } } else if(currx == 0) { if(exit_type == 2) { done = 1; } } else { // Move all back 1, decreasing string length memmove(string + currx - 1, string + currx, curr_len - currx + 1); curr_len--; // Cursor back one currx--; } break; } case IKEY_DELETE: { // Delete, at the end might exit if(currx == curr_len) { if(exit_type == 2) done = 1; } else { if(curr_len) { // Move all back 1, decreasing string length memmove(string + currx, string + currx + 1, curr_len - currx); curr_len--; } } break; } case IKEY_c: { if(get_ctrl_status(keycode_internal) && robo_intk) { done = 1; } else if(get_alt_status(keycode_internal) && !filter_type) { // If alt - C is pressed, choose character int new_char = char_selection(last_char); if(new_char >= 32) { cur_char = new_char; last_char = new_char; place = 1; } else { place = 0; } } else { place = 1; } break; } case IKEY_t: { if(get_alt_status(keycode_internal)) { done = 1; } else { place = 1; } break; } case IKEY_l: case IKEY_g: case IKEY_d: case IKEY_f: case IKEY_r: { if(get_ctrl_status(keycode_internal) && robo_intk) { done = 1; } else { place = 1; } break; } case IKEY_i: { if((get_ctrl_status(keycode_internal) || get_alt_status(keycode_internal)) && robo_intk) { done = 1; } else { place = 1; } break; } case IKEY_u: case IKEY_o: case IKEY_x: case IKEY_b: case IKEY_s: case IKEY_e: case IKEY_v: case IKEY_p: case IKEY_h: case IKEY_m: { if(get_alt_status(keycode_internal) && robo_intk) { done = 1; } else { place = 1; } break; } case IKEY_LSHIFT: case IKEY_RSHIFT: case 0: { place = 0; break; } default: { // Place the char place = 1; break; } case -1: { break; } } if(place) { if((cur_char < 32) && (exit_type == 2)) { done = 1; key = cur_char; } else // Keycode.. Filter. if(filter_type & 1) { if((cur_char >= 'a') && (cur_char <= 'z')) cur_char -= 32; } if(filter_type & 2) { if((cur_char >= 'A') && (cur_char <= 'Z')) cur_char += 32; } // Block numbers if((filter_type & 4) && ((cur_char >= '0') && (cur_char <= '9'))) { place = 0; } // Block alpha if((filter_type & 8) && (((cur_char >= 'a') && (cur_char <= 'z')) || ((cur_char >= 'A') && (cur_char <= 'Z')))) { place = 0; } // Block spaces if((filter_type & 16) && (cur_char == ' ')) { place = 0; } // Block high-ASCII if((filter_type & 32) && (cur_char > 126)) { place = 0; } // Block these chars if((filter_type & 64) && ((cur_char == '*') || (cur_char == '[') || (cur_char == ']') || (cur_char == '>') || (cur_char == '<') || (cur_char == ',') || (cur_char == '|') || (cur_char == '?') || (cur_char == '=') || (cur_char == ';') || (cur_char == '\"') || (cur_char =='/'))) { place = 0; } // Block these chars if((filter_type & 128) && ((cur_char == ':') || (cur_char == '\\'))) { place = 0; } // Block these chars if((filter_type & 256) && (((cur_char > ' ') && (cur_char < '0')) || ((cur_char > '9') && (cur_char < 'A')) || ((cur_char > 'Z') && (cur_char < 'a')) || ((cur_char > 'z') && (cur_char < 127)))) { place = 0; } // Now, can it still be placed? if(place && (curr_len != max_len) && (!done) && cur_char) { // Overwrite or insert? if((insert_on) || (currx == curr_len)) { // Insert- Move all ahead 1, increasing string length curr_len++; memmove(string + currx + 1, string + currx, curr_len - currx); } // Add character and move forward one string[currx++] = cur_char; } } // Move cursor if(robo_intk && (currx > 75)) move_cursor(77, y); else move_cursor(x + currx, y); if(insert_on) cursor_underline(); else cursor_solid(); // Loop } while(!done); cursor_off(); if(return_x_pos) *return_x_pos = currx; return key; }
int main(int argc, char **argv) { float bitcoins = 25.0; if (argc > 1) bitcoins = atof(argv[1]); signal(SIGINT, sighandler); cursor_off(); clear(); float usd_btc_last = 0; float usd_btc = 0; do { float eur_in_usd = get_eur_in_usd(); float usd_in_nok = get_usd_in_nok(); if (argc > 2) usd_btc = atof(argv[2]); if (mtgox) { time_t btc_time = mtgox_time(); struct tm *tm = localtime(&btc_time); char timebuf[16]; sprintf(timebuf, "%02u:%02u:%02u", tm->tm_hour, tm->tm_min, tm->tm_sec); usd_btc = mtgox_usd(); printf("\r%s%s%.04f%s$ #BTC: %.02f TOTAL: { %sUSD: %.02f, EUR: %.02f, NOK: %.02f%s } USD in NOK: %.04f, EXCHANGE SAMPLED: %s", COLOR_BOLD, usd_btc_last <= usd_btc ? COLOR_GREEN : COLOR_RED, usd_btc, COLOR_NORMAL, bitcoins, COLOR_BOLD, bitcoins * usd_btc, (bitcoins * usd_btc) / eur_in_usd, (bitcoins * usd_btc) * usd_in_nok, COLOR_NORMAL, usd_in_nok, timebuf ); } else { usd_btc = bitcoin24_usd(); printf("\r%s%s%.04f%s$ #BTC: %.02f TOTAL: { %sUSD: %.02f, EUR: %.02f, NOK: %.02f%s } USD in NOK: %.04f", COLOR_BOLD, usd_btc_last <= usd_btc ? COLOR_GREEN : COLOR_RED, usd_btc, COLOR_NORMAL, bitcoins, COLOR_BOLD, bitcoins * usd_btc, (bitcoins * usd_btc) / eur_in_usd, (bitcoins * usd_btc) * usd_in_nok, COLOR_NORMAL, usd_in_nok ); } fflush(stdout); sleep(10); usd_btc_last = usd_btc; } while(1); cursor_on(); return 0; }
void title_screen(void){ char j,k,choice; while(1){ stop = 1; players = team = demo = choice = tt = 0; init_msx(2); title_irq(); cursor_off(); memmove((char*)0xd800,(char*)(&bmp_data + LINES*40 + LINES*320),LINES*40); // memset((char*)0xcea8,0xff,40); fill(); revers(1); textcolor(1); cputsxy(12,18, "one player game"); textcolor(2); cputsxy(12,19, "two player team"); textcolor(7); cputsxy(11,20, "two player battle"); textcolor(2); cputsxy(15,21, "highscores"); // textcolor(1); cputsxy(18,22, "demo"); while (!demo){ do_bar(choice); j = *(char*)0xdc00; if (j == 111) break; if (j == 126){ if (choice){ for (k=0;k<8;++k){ do_bar(--choice); } } } else if (j == 125){ if (choice < 24){ for (k=0;k<8;++k){ do_bar(++choice); } } } } if (demo) break; choice>>=3; if (choice == 1){ team = 1; } else if (choice == 2){ players = 1; } else if (choice == 3){ game_irq(); show_highscores(); continue; } break; } fld(17); while (!fld_done); game_irq(); // gfx_mode(); fill(); *(char*)0xd016 = 0x10; delay (35); if (demo){ txt_mode(); print2x2_centered("demo mode",7,8,10); delay(255); } }
void help_system(struct world *mzx_world) { char file[13], file2[13], label[13]; int where, offs, size, t1, t2; enum cursor_mode_types old_cmode; FILE *fp; fp = mzx_world->help_file; if(!fp) return; old_cmode = get_cursor_mode(); rewind(fp); t1 = fgetw(fp); fseek(fp, t1 * 21 + 4 + get_context() * 12, SEEK_SET); // At proper context info where = fgetd(fp); // Where file to load is size = fgetd(fp); // Size of file to load offs = fgetd(fp); // Offset within file of link // Jump to file fseek(fp, where, SEEK_SET); // Read it in fread(help, 1, size, fp); // Display it cursor_off(); labelled: help_display(mzx_world, help, offs, file, label); // File? if(file[0]) { // Yep. Search for file. fseek(fp, 2, SEEK_SET); for(t2 = 0; t2 < t1; t2++) { fread(file2, 1, 13, fp); if(!strcmp(file, file2)) break; fseek(fp, 8, SEEK_CUR); } if(t2 < t1) { // Found file. where = fgetd(fp); size = fgetd(fp); fseek(fp, where, SEEK_SET); fread(help, 1, size, fp); // Search for label for(t2 = 0; t2 < size; t2++) { if(help[t2] != 255) continue; if(help[t2 + 1] != ':') continue; if(!strcmp(help + t2 + 3, label)) break; // Found label! } if(t2 < size) { // Found label. t2 is offset. offs = t2; goto labelled; } } } set_cursor_mode(old_cmode); }
void normal() { register int c; long n; int flag = FALSE; int flag2 = FALSE; int type = 0; /* type of operation */ int dir = FORWARD; /* search direction */ int nchar = NUL; int finish_op; linenr_t Prenum1; char_u searchbuff[CMDBUFFSIZE];/* buffer for search string */ FPOS *pos = NULL; /* init for gcc */ register char_u *ptr; int command_busy = FALSE; static int didwarn = FALSE; /* warned for broken inversion */ int modified = FALSE; /* changed current buffer */ int ctrl_w = FALSE; /* got CTRL-W command */ /* the visual area is remembered for reselection */ static linenr_t resel_Visual_nlines; /* number of lines */ static int resel_Visual_type = 0; /* type 'v', 'V' or CTRL-V */ static colnr_t resel_Visual_col; /* number of columns or end column */ /* the visual area is remembered for redo */ static linenr_t redo_Visual_nlines; /* number of lines */ static int redo_Visual_type = 0; /* type 'v', 'V' or CTRL-V */ static colnr_t redo_Visual_col; /* number of columns or end column */ static long redo_Visual_Prenum; /* Prenum for operator */ Prenum = 0; /* * If there is an operator pending, then the command we take this time * will terminate it. Finish_op tells us to finish the operation before * returning this time (unless the operation was cancelled). */ finish_op = (operator != NOP); if (!finish_op && !yankbuffer) opnum = 0; if (p_sc && (vpeekc() == NUL || KeyTyped == TRUE)) premsg(NUL, NUL); State = NORMAL_BUSY; c = vgetc(); getcount: /* Pick up any leading digits and compute 'Prenum' */ while ((c >= '1' && c <= '9') || (Prenum != 0 && (c == DEL || c == '0'))) { if (c == DEL) Prenum /= 10; else Prenum = Prenum * 10 + (c - '0'); if (Prenum < 0) /* got too large! */ Prenum = 999999999; premsg(ctrl_w ? Ctrl('W') : ' ', NUL); c = vgetc(); } /* * If we got CTRL-W there may be a/another count */ if (c == Ctrl('W') && !ctrl_w) { ctrl_w = TRUE; opnum = Prenum; /* remember first count */ Prenum = 0; State = ONLYKEY; /* no mapping for nchar, but keys */ premsg(c, NUL); c = vgetc(); /* get next character */ goto getcount; /* jump back */ } /* * If we're in the middle of an operator (including after entering a yank * buffer with ") AND we had a count before the * operator, then that count overrides the current value of Prenum. What * this means effectively, is that commands like "3dw" get turned into * "d3w" which makes things fall into place pretty neatly. * If you give a count before AND after the operator, they are multiplied. */ if (opnum != 0) { if (Prenum) Prenum *= opnum; else Prenum = opnum; opnum = 0; } Prenum1 = (Prenum == 0 ? 1 : Prenum); /* Prenum often defaults to 1 */ premsg(c, NUL); /* * get an additional character if we need one * for CTRL-W we already got it when looking for a count */ if (ctrl_w) { nchar = c; c = Ctrl('W'); premsg(c, nchar); } else if (strchr("@zZtTfF[]mg'`\"", c) || (c == 'q' && !Recording && !Exec_reg) || (c == 'r' && !VIsual.lnum)) { State = NOMAPPING; nchar = vgetc(); /* no macro mapping for this char */ premsg(c, nchar); } if (p_sc) flushbuf(); /* flush the premsg() characters onto the screen so we can see them while the command is being executed */ /* * For commands that don't get another character we can put the State back to * NORMAL and check for a window size change. */ if (STRCHR("z:/?", c) == NULL) State = NORMAL; if (nchar == ESC) { CLEAROP; goto normal_end; } switch (c) { /* * 0: Macros */ case 'q': /* (stop) recording into a named register */ CHECKCLEAROP; /* command is ignored while executing a register */ if (!Exec_reg && dorecord(nchar) == FAIL) CLEAROPBEEP; break; case '@': /* execute a named buffer */ CHECKCLEAROP; while (Prenum1--) { if (doexecbuf(nchar) == FAIL) { CLEAROPBEEP; break; } } break; /* * 1: Screen positioning commands */ case Ctrl('D'): flag = TRUE; case Ctrl('U'): CHECKCLEAROP; if (Prenum) curwin->w_p_scroll = (Prenum > curwin->w_height) ? curwin->w_height : Prenum; n = (curwin->w_p_scroll <= curwin->w_height) ? curwin->w_p_scroll : curwin->w_height; if (flag) { curwin->w_topline += n; if (curwin->w_topline > curbuf->b_ml.ml_line_count) curwin->w_topline = curbuf->b_ml.ml_line_count; comp_Botline(curwin); /* compute curwin->w_botline */ (void)onedown(n); } else { if (n >= curwin->w_cursor.lnum) n = curwin->w_cursor.lnum - 1; Prenum1 = curwin->w_cursor.lnum - n; scrolldown(n); if (Prenum1 < curwin->w_cursor.lnum) curwin->w_cursor.lnum = Prenum1; } beginline(TRUE); updateScreen(VALID); break; case Ctrl('B'): case K_SUARROW: dir = BACKWARD; case Ctrl('F'): case K_SDARROW: CHECKCLEAROP; (void)onepage(dir, Prenum1); break; case Ctrl('E'): CHECKCLEAROP; scrollup(Prenum1); /* We may have moved to another line -- webb */ coladvance(curwin->w_curswant); updateScreen(VALID); break; case Ctrl('Y'): CHECKCLEAROP; scrolldown(Prenum1); /* We may have moved to another line -- webb */ coladvance(curwin->w_curswant); updateScreen(VALID); break; case 'z': CHECKCLEAROP; if (isdigit(nchar)) { /* * we misuse some variables to be able to call premsg() */ operator = c; opnum = Prenum; Prenum = nchar - '0'; for (;;) { premsg(' ', NUL); nchar = vgetc(); State = NORMAL; if (nchar == DEL) Prenum /= 10; else if (isdigit(nchar)) Prenum = Prenum * 10 + (nchar - '0'); else if (nchar == CR) { win_setheight((int)Prenum); break; } else { CLEAROPBEEP; break; } } operator = NOP; break; } if (Prenum && Prenum != curwin->w_cursor.lnum) /* line number given */ { setpcmark(); if (Prenum > curbuf->b_ml.ml_line_count) curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; else curwin->w_cursor.lnum = Prenum; } State = NORMAL; /* for updateScreen() */ switch (nchar) { case NL: /* put curwin->w_cursor at top of screen */ case CR: beginline(TRUE); case 't': curwin->w_topline = curwin->w_cursor.lnum; break; case '.': /* put curwin->w_cursor in middle of screen */ case 'z': n = (curwin->w_height + plines(curwin->w_cursor.lnum)) / 2; goto dozcmd; case '-': /* put curwin->w_cursor at bottom of screen */ case 'b': n = curwin->w_height; /* FALLTHROUGH */ dozcmd: { register linenr_t lp = curwin->w_cursor.lnum; register long l = plines(lp); do { curwin->w_topline = lp; if (--lp == 0) break; l += plines(lp); } while (l <= n); } if (nchar != 'z' && nchar != 'b') beginline(TRUE); break; case Ctrl('S'): /* ignore CTRL-S and CTRL-Q to avoid problems */ case Ctrl('Q'): /* with terminals that use xon/xoff */ break; default: CLEAROPBEEP; } updateScreen(VALID); break; /* * 2: Control commands */ case ':': if (VIsual.lnum) goto dooperator; CHECKCLEAROP; /* * translate "count:" into ":.,.+(count - 1)" */ if (Prenum) { stuffReadbuff((char_u *)"."); if (Prenum > 1) { stuffReadbuff((char_u *)",.+"); stuffnumReadbuff((long)Prenum - 1L); } } docmdline(NULL); modified = TRUE; break; case K_HELP: CHECKCLEAROP; help(); break; case Ctrl('L'): CHECKCLEAROP; updateScreen(CLEAR); break; case Ctrl('G'): CHECKCLEAROP; fileinfo(did_cd || Prenum); /* print full name if count given or :cd used */ break; case K_CCIRCM: /* CTRL-^, short for ":e #" */ CHECKCLEAROPQ; (void)buflist_getfile((int)Prenum, (linenr_t)0, TRUE); break; case 'Z': /* write, if changed, and exit */ CHECKCLEAROPQ; if (nchar != 'Z') { CLEAROPBEEP; break; } stuffReadbuff((char_u *)":x\n"); break; case Ctrl(']'): /* :ta to current identifier */ CHECKCLEAROPQ; case '*': /* / to current identifier or string */ case '#': /* ? to current identifier or string */ case 'K': /* run program for current identifier */ { register int col; register int i; /* * if i == 0: try to find an identifier * if i == 1: try to find any string */ ptr = ml_get(curwin->w_cursor.lnum); for (i = 0; i < 2; ++i) { /* * skip to start of identifier/string */ col = curwin->w_cursor.col; while (ptr[col] != NUL && (i == 0 ? !isidchar(ptr[col]) : iswhite(ptr[col]))) ++col; /* * Back up to start of identifier/string. This doesn't match the * real vi but I like it a little better and it shouldn't bother * anyone. */ while (col > 0 && (i == 0 ? isidchar(ptr[col - 1]) : (!iswhite(ptr[col - 1]) && !isidchar(ptr[col - 1])))) --col; /* * if identifier found or not '*' or '#' command, stop searching */ if (isidchar(ptr[col]) || (c != '*' && c != '#')) break; } /* * did't find an identifier of string */ if (ptr[col] == NUL || (!isidchar(ptr[col]) && i == 0)) { CLEAROPBEEP; break; } if (Prenum) stuffnumReadbuff(Prenum); switch (c) { case '*': stuffReadbuff((char_u *)"/"); goto sow; case '#': stuffReadbuff((char_u *)"?"); sow: if (i == 0) stuffReadbuff((char_u *)"\\<"); break; case 'K': stuffReadbuff((char_u *)":! "); stuffReadbuff(p_kp); stuffReadbuff((char_u *)" "); break; default: stuffReadbuff((char_u *)":ta "); } /* * Now grab the chars in the identifier */ while (i == 0 ? isidchar(ptr[col]) : (ptr[col] != NUL && !iswhite(ptr[col]))) { stuffcharReadbuff(ptr[col]); ++col; } if ((c == '*' || c == '#') && i == 0) stuffReadbuff((char_u *)"\\>"); stuffReadbuff((char_u *)"\n"); } break; case Ctrl('T'): /* backwards in tag stack */ CHECKCLEAROPQ; dotag((char_u *)"", 2, (int)Prenum1); break; /* * Cursor motions */ case 'G': mtype = MLINE; setpcmark(); if (Prenum == 0 || Prenum > curbuf->b_ml.ml_line_count) curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; else curwin->w_cursor.lnum = Prenum; beginline(TRUE); break; case 'H': case 'M': if (c == 'M') n = (curwin->w_height - curwin->w_empty_rows) / 2; else n = Prenum; mtype = MLINE; setpcmark(); curwin->w_cursor.lnum = curwin->w_topline; while (n && onedown((long)1) == OK) --n; beginline(TRUE); break; case 'L': mtype = MLINE; setpcmark(); curwin->w_cursor.lnum = curwin->w_botline - 1; for (n = Prenum; n && oneup((long)1) == OK; n--) ; beginline(TRUE); break; case 'l': case K_RARROW: case ' ': mtype = MCHAR; mincl = FALSE; n = Prenum1; while (n--) { if (oneright() == FAIL) { /* space wraps to next line if 'whichwrap' bit 1 set */ /* 'l' wraps to next line if 'whichwrap' bit 2 set */ /* CURS_RIGHT wraps to next line if 'whichwrap' bit 3 set */ if (((c == ' ' && (p_ww & 2)) || (c == 'l' && (p_ww & 4)) || (c == K_RARROW && (p_ww & 8))) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { ++curwin->w_cursor.lnum; curwin->w_cursor.col = 0; curwin->w_set_curswant = TRUE; continue; } if (operator == NOP) beep(); else { if (lineempty(curwin->w_cursor.lnum)) CLEAROPBEEP; else { mincl = TRUE; if (n) beep(); } } break; } } break; case Ctrl('H'): case 'h': case K_LARROW: case DEL: mtype = MCHAR; mincl = FALSE; n = Prenum1; while (n--) { if (oneleft() == FAIL) { /* backspace and del wrap to previous line if 'whichwrap' * bit 0 set */ /* 'h' wraps to previous line if 'whichwrap' bit 2 set */ /* CURS_LEFT wraps to previous line if 'whichwrap' bit 3 set */ if ((((c == Ctrl('H') || c == DEL) && (p_ww & 1)) || (c == 'h' && (p_ww & 4)) || (c == K_LARROW && (p_ww & 8))) && curwin->w_cursor.lnum > 1) { --(curwin->w_cursor.lnum); coladvance(MAXCOL); curwin->w_set_curswant = TRUE; continue; } else if (operator != DELETE && operator != CHANGE) beep(); else if (Prenum1 == 1) CLEAROPBEEP; break; } } break; case '-': flag = TRUE; /* FALLTHROUGH */ case 'k': case K_UARROW: case Ctrl('P'): mtype = MLINE; if (oneup(Prenum1) == FAIL) CLEAROPBEEP; else if (flag) beginline(TRUE); break; case '+': case CR: flag = TRUE; /* FALLTHROUGH */ case 'j': case K_DARROW: case Ctrl('N'): case NL: mtype = MLINE; if (onedown(Prenum1) == FAIL) CLEAROPBEEP; else if (flag) beginline(TRUE); break; /* * This is a strange motion command that helps make operators more * logical. It is actually implemented, but not documented in the * real 'vi'. This motion command actually refers to "the current * line". Commands like "dd" and "yy" are really an alternate form of * "d_" and "y_". It does accept a count, so "d3_" works to delete 3 * lines. */ case '_': lineop: mtype = MLINE; if (onedown((long)(Prenum1 - 1)) == FAIL) CLEAROPBEEP; if (operator != YANK) /* 'Y' does not move cursor */ beginline(TRUE); break; case '|': mtype = MCHAR; mincl = TRUE; beginline(FALSE); if (Prenum > 0) coladvance((colnr_t)(Prenum - 1)); curwin->w_curswant = (colnr_t)(Prenum - 1); /* keep curswant at the column where we wanted to go, not where we ended; differs is line is too short */ curwin->w_set_curswant = FALSE; break; /* * Word Motions */ case 'B': type = 1; /* FALLTHROUGH */ case 'b': case K_SLARROW: mtype = MCHAR; mincl = FALSE; curwin->w_set_curswant = TRUE; if (bck_word(Prenum1, type)) CLEAROPBEEP; break; case 'E': type = 1; /* FALLTHROUGH */ case 'e': mincl = TRUE; goto dowrdcmd; case 'W': type = 1; /* FALLTHROUGH */ case 'w': case K_SRARROW: mincl = FALSE; flag = TRUE; /* * This is a little strange. To match what the real vi does, we * effectively map 'cw' to 'ce', and 'cW' to 'cE', provided that we are * not on a space or a TAB. This seems * impolite at first, but it's really more what we mean when we say * 'cw'. * Another strangeness: When standing on the end of a word "ce" will * change until the end of the next wordt, but "cw" will change only * one character! This is done by setting type to 2. */ if (operator == CHANGE && (n = gchar_cursor()) != ' ' && n != TAB && n != NUL) { mincl = TRUE; flag = FALSE; flag2 = TRUE; } dowrdcmd: mtype = MCHAR; curwin->w_set_curswant = TRUE; if (flag) n = fwd_word(Prenum1, type, operator != NOP); else n = end_word(Prenum1, type, flag2); if (n) { CLEAROPBEEP; break; } #if 0 /* * If we do a 'dw' for the last word in a line, we only delete the rest * of the line, not joining the two lines, unless the current line is empty. */ if (operator == DELETE && Prenum1 == 1 && curbuf->b_startop.lnum != curwin->w_cursor.lnum && !lineempty(startop.lnum)) { curwin->w_cursor = curbuf->b_startop; while (oneright() == OK) ; mincl = TRUE; } #endif break; case '$': mtype = MCHAR; mincl = TRUE; curwin->w_curswant = MAXCOL; /* so we stay at the end */ if (onedown((long)(Prenum1 - 1)) == FAIL) { CLEAROPBEEP; break; } break; case '^': flag = TRUE; /* FALLTHROUGH */ case '0': mtype = MCHAR; mincl = FALSE; beginline(flag); break; /* * 4: Searches */ case '?': case '/': if (!getcmdline(c, searchbuff)) { CLEAROP; break; } mtype = MCHAR; mincl = FALSE; curwin->w_set_curswant = TRUE; n = dosearch(c, searchbuff, FALSE, Prenum1, TRUE, TRUE); if (n == 0) CLEAROP; else if (n == 2) mtype = MLINE; break; case 'N': flag = 1; case 'n': mtype = MCHAR; mincl = FALSE; curwin->w_set_curswant = TRUE; if (!dosearch(0, NULL, flag, Prenum1, TRUE, TRUE)) CLEAROP; break; /* * Character searches */ case 'T': dir = BACKWARD; /* FALLTHROUGH */ case 't': type = 1; goto docsearch; case 'F': dir = BACKWARD; /* FALLTHROUGH */ case 'f': docsearch: mtype = MCHAR; if (dir == BACKWARD) mincl = FALSE; else mincl = TRUE; curwin->w_set_curswant = TRUE; if (!searchc(nchar, dir, type, Prenum1)) CLEAROPBEEP; break; case ',': flag = 1; /* FALLTHROUGH */ case ';': dir = flag; goto docsearch; /* nchar == NUL, thus repeat previous search */ /* * section or C function searches */ case '[': dir = BACKWARD; /* FALLTHROUGH */ case ']': mtype = MCHAR; mincl = FALSE; /* * "[f" or "]f" : Edit file under the cursor (same as "gf") */ if ((c == ']' || c == '[') && nchar == 'f') goto gotofile; /* * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')' */ if ((c == '[' && (nchar == '{' || nchar == '(')) || ((c == ']' && (nchar == '}' || nchar == ')')))) { FPOS old_pos; old_pos = curwin->w_cursor; while (Prenum1--) { if ((pos = showmatch(nchar)) == NULL) { CLEAROPBEEP; break; } curwin->w_cursor = *pos; } curwin->w_cursor = old_pos; if (pos != NULL) { setpcmark(); curwin->w_cursor = *pos; curwin->w_set_curswant = TRUE; } break; } /* * "[[", "[]", "]]" and "][": move to start or end of function */ if (nchar == '[' || nchar == ']') { if (nchar == c) /* "]]" or "[[" */ flag = '{'; else flag = '}'; /* "][" or "[]" */ curwin->w_set_curswant = TRUE; /* * Imitate strange vi behaviour: When using "]]" with an operator we * also stop at '}'. */ if (!findpar(dir, Prenum1, flag, (operator != NOP && dir == FORWARD && flag == '{'))) CLEAROPBEEP; break; } /* * "[p" and "]p": put with indent adjustment */ if (nchar == 'p') { doput((c == ']') ? FORWARD : BACKWARD, Prenum1, TRUE); modified = TRUE; break; } /* * end of '[' and ']': not a valid nchar */ CLEAROPBEEP; break; case '%': mincl = TRUE; if (Prenum) /* {cnt}% : goto {cnt} percentage in file */ { if (Prenum > 100) CLEAROPBEEP; else { mtype = MLINE; setpcmark(); /* round up, so CTRL-G will give same value */ curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count * Prenum + 99) / 100; beginline(TRUE); } } else /* % : go to matching paren */ { mtype = MCHAR; if ((pos = showmatch(NUL)) == NULL) CLEAROPBEEP; else { setpcmark(); curwin->w_cursor = *pos; curwin->w_set_curswant = TRUE; } } break; case '(': dir = BACKWARD; /* FALLTHROUGH */ case ')': mtype = MCHAR; if (c == ')') mincl = FALSE; else mincl = TRUE; curwin->w_set_curswant = TRUE; if (!findsent(dir, Prenum1)) CLEAROPBEEP; break; case '{': dir = BACKWARD; /* FALLTHROUGH */ case '}': mtype = MCHAR; mincl = FALSE; curwin->w_set_curswant = TRUE; if (!findpar(dir, Prenum1, NUL, FALSE)) CLEAROPBEEP; break; /* * 5: Edits */ case '.': CHECKCLEAROPQ; if (start_redo(Prenum) == FAIL) CLEAROPBEEP; modified = TRUE; break; case 'u': if (VIsual.lnum) goto dooperator; case K_UNDO: CHECKCLEAROPQ; u_undo((int)Prenum1); curwin->w_set_curswant = TRUE; modified = TRUE; break; case Ctrl('R'): CHECKCLEAROPQ; u_redo((int)Prenum1); curwin->w_set_curswant = TRUE; modified = TRUE; break; case 'U': if (VIsual.lnum) goto dooperator; CHECKCLEAROPQ; u_undoline(); curwin->w_set_curswant = TRUE; modified = TRUE; break; case 'r': if (VIsual.lnum) { c = 'c'; goto dooperator; } CHECKCLEAROPQ; ptr = ml_get_cursor(); if (STRLEN(ptr) < (unsigned)Prenum1) /* not enough characters to replace */ { CLEAROPBEEP; break; } /* * Replacing with a line break or tab is done by edit(), because it * is complicated. * Other characters are done below to avoid problems with things like * CTRL-V 048 (for edit() this would be R CTRL-V 0 ESC). */ if (nchar == '\r' || nchar == '\n' || nchar == '\t') { prep_redo(Prenum1, 'r', nchar, NUL); stuffnumReadbuff(Prenum1); stuffcharReadbuff('R'); stuffcharReadbuff(nchar); stuffcharReadbuff(ESC); break; } if (nchar == Ctrl('V')) /* get another character */ { c = Ctrl('V'); nchar = get_literal(&type); if (type) /* typeahead */ stuffcharReadbuff(type); } else c = NUL; prep_redo(Prenum1, 'r', c, nchar); if (!u_save_cursor()) /* save line for undo */ break; /* * Get ptr again, because u_save will have released the line. * At the same time we let know that the line will be changed. */ ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE) + curwin->w_cursor.col; curwin->w_cursor.col += Prenum1 - 1; while (Prenum1--) /* replace the characters */ *ptr++ = nchar; curwin->w_set_curswant = TRUE; CHANGED; updateline(); modified = TRUE; break; case 'J': if (VIsual.lnum) /* join the visual lines */ { if (curwin->w_cursor.lnum > VIsual.lnum) { Prenum = curwin->w_cursor.lnum - VIsual.lnum + 1; curwin->w_cursor.lnum = VIsual.lnum; } else Prenum = VIsual.lnum - curwin->w_cursor.lnum + 1; VIsual.lnum = 0; } CHECKCLEAROP; if (Prenum <= 1) Prenum = 2; /* default for join is two lines! */ if (curwin->w_cursor.lnum + Prenum - 1 > curbuf->b_ml.ml_line_count) /* beyond last line */ { CLEAROPBEEP; break; } prep_redo(Prenum, 'J', NUL, NUL); dodojoin(Prenum, TRUE, TRUE); modified = TRUE; break; case 'P': dir = BACKWARD; /* FALLTHROUGH */ case 'p': CHECKCLEAROPQ; prep_redo(Prenum, c, NUL, NUL); doput(dir, Prenum1, FALSE); modified = TRUE; break; case Ctrl('A'): /* add to number */ case Ctrl('X'): /* subtract from number */ CHECKCLEAROPQ; if (doaddsub((int)c, Prenum1) == OK) prep_redo(Prenum1, c, NUL, NUL); modified = TRUE; break; /* * 6: Inserts */ case 'A': curwin->w_set_curswant = TRUE; while (oneright() == OK) ; /* FALLTHROUGH */ case 'a': CHECKCLEAROPQ; /* Works just like an 'i'nsert on the next character. */ if (u_save_cursor()) { if (!lineempty(curwin->w_cursor.lnum)) inc_cursor(); startinsert(c, FALSE, Prenum1); modified = TRUE; command_busy = TRUE; } break; case 'I': beginline(TRUE); /* FALLTHROUGH */ case 'i': CHECKCLEAROPQ; if (u_save_cursor()) { startinsert(c, FALSE, Prenum1); modified = TRUE; command_busy = TRUE; } break; case 'o': if (VIsual.lnum) /* switch start and end of visual */ { Prenum = VIsual.lnum; VIsual.lnum = curwin->w_cursor.lnum; curwin->w_cursor.lnum = Prenum; if (VIsual.col != VISUALLINE) { n = VIsual.col; VIsual.col = curwin->w_cursor.col; curwin->w_cursor.col = (int)n; curwin->w_set_curswant = TRUE; } break; } CHECKCLEAROP; if (u_save(curwin->w_cursor.lnum, (linenr_t)(curwin->w_cursor.lnum + 1)) && Opencmd(FORWARD, TRUE, TRUE)) { startinsert('o', TRUE, Prenum1); modified = TRUE; command_busy = TRUE; } break; case 'O': CHECKCLEAROPQ; if (u_save((linenr_t)(curwin->w_cursor.lnum - 1), curwin->w_cursor.lnum) && Opencmd(BACKWARD, TRUE, TRUE)) { startinsert('O', TRUE, Prenum1); modified = TRUE; command_busy = TRUE; } break; case 'R': if (VIsual.lnum) { c = 'c'; VIsual.col = VISUALLINE; goto dooperator; } CHECKCLEAROPQ; if (u_save_cursor()) { startinsert('R', FALSE, Prenum1); modified = TRUE; command_busy = TRUE; } break; /* * 7: Operators */ case '~': /* swap case */ /* * if tilde is not an operator and Visual is off: swap case * of a single character */ if (!p_to && !VIsual.lnum) { CHECKCLEAROPQ; if (lineempty(curwin->w_cursor.lnum)) { CLEAROPBEEP; break; } prep_redo(Prenum, '~', NUL, NUL); if (!u_save_cursor()) break; for (; Prenum1 > 0; --Prenum1) { if (gchar_cursor() == NUL) break; swapchar(&curwin->w_cursor); inc_cursor(); } curwin->w_set_curswant = TRUE; CHANGED; updateline(); modified = TRUE; break; } /*FALLTHROUGH*/ case 'd': case 'c': case 'y': case '>': case '<': case '!': case '=': case 'Q': dooperator: n = STRCHR(opchars, c) - opchars + 1; if (n == operator) /* double operator works on lines */ goto lineop; CHECKCLEAROP; if (Prenum != 0) opnum = Prenum; curbuf->b_startop = curwin->w_cursor; operator = (int)n; break; /* * 8: Abbreviations */ /* when Visual the next commands are operators */ case 'S': case 'Y': case 'D': case 'C': case 'x': case 'X': case 's': if (VIsual.lnum) { static char_u trans[] = "ScYyDdCcxdXdsc"; if (isupper(c) && !Visual_block) /* uppercase means linewise */ VIsual.col = VISUALLINE; c = *(STRCHR(trans, c) + 1); goto dooperator; } case '&': CHECKCLEAROPQ; if (Prenum) stuffnumReadbuff(Prenum); if (c == 'Y' && p_ye) c = 'Z'; { static char_u *(ar[9]) = {(char_u *)"dl", (char_u *)"dh", (char_u *)"d$", (char_u *)"c$", (char_u *)"cl", (char_u *)"cc", (char_u *)"yy", (char_u *)"y$", (char_u *)":s\r"}; static char_u *str = (char_u *)"xXDCsSYZ&"; stuffReadbuff(ar[(int)(STRCHR(str, c) - str)]); } break; /* * 9: Marks */ case 'm': CHECKCLEAROP; if (setmark(nchar) == FAIL) CLEAROPBEEP; break; case '\'': flag = TRUE; /* FALLTHROUGH */ case '`': pos = getmark(nchar, (operator == NOP)); if (pos == (FPOS *)-1) /* jumped to other file */ { if (flag) beginline(TRUE); break; } if (pos != NULL) setpcmark(); cursormark: if (pos == NULL || pos->lnum == 0) CLEAROPBEEP; else { curwin->w_cursor = *pos; if (flag) beginline(TRUE); } mtype = flag ? MLINE : MCHAR; mincl = FALSE; /* ignored if not MCHAR */ curwin->w_set_curswant = TRUE; break; case Ctrl('O'): /* goto older pcmark */ Prenum1 = -Prenum1; /* FALLTHROUGH */ case Ctrl('I'): /* goto newer pcmark */ CHECKCLEAROPQ; pos = movemark((int)Prenum1); if (pos == (FPOS *)-1) /* jump to other file */ { curwin->w_set_curswant = TRUE; break; } goto cursormark; /* * 10. Buffer setting */ case '"': CHECKCLEAROP; if (nchar != NUL && is_yank_buffer(nchar, FALSE)) { yankbuffer = nchar; opnum = Prenum; /* remember count before '"' */ } else CLEAROPBEEP; break; /* * 11. Visual */ case 'v': case 'V': case Ctrl('V'): CHECKCLEAROP; Visual_block = FALSE; /* stop Visual */ if (VIsual.lnum) { VIsual.lnum = 0; updateScreen(NOT_VALID); /* delete the inversion */ } /* start Visual */ else { if (!didwarn && set_highlight('v') == FAIL)/* cannot highlight */ { EMSG("Warning: terminal cannot highlight"); didwarn = TRUE; } if (Prenum) /* use previously selected part */ { if (!resel_Visual_type) /* there is none */ { beep(); break; } VIsual = curwin->w_cursor; if (resel_Visual_nlines > 1) curwin->w_cursor.lnum += resel_Visual_nlines * Prenum - 1; switch (resel_Visual_type) { case 'V': VIsual.col = VISUALLINE; break; case Ctrl('V'): Visual_block = TRUE; break; case 'v': if (resel_Visual_nlines <= 1) curwin->w_cursor.col += resel_Visual_col * Prenum - 1; else curwin->w_cursor.col = resel_Visual_col; break; } if (resel_Visual_col == MAXCOL) { curwin->w_curswant = MAXCOL; coladvance(MAXCOL); } else if (Visual_block) coladvance((colnr_t)(curwin->w_virtcol + resel_Visual_col * Prenum - 1)); curs_columns(TRUE); /* recompute w_virtcol */ updateScreen(NOT_VALID); /* show the inversion */ } else { VIsual = curwin->w_cursor; if (c == 'V') /* linewise */ VIsual.col = VISUALLINE; else if (c == Ctrl('V')) /* blockwise */ Visual_block = TRUE; updateline(); /* start the inversion */ } } break; /* * 12. Suspend */ case Ctrl('Z'): CLEAROP; VIsual.lnum = 0; /* stop Visual */ stuffReadbuff((char_u *)":st\r"); /* with autowrite */ break; /* * 13. Window commands */ case Ctrl('W'): CHECKCLEAROP; do_window(nchar, Prenum); /* everything is in window.c */ break; /* * 14. extended commands (starting with 'g') */ case 'g': switch (nchar) { /* * "gf": goto file, edit file under cursor * "]f" and "[f": can also be used. */ case 'f': gotofile: ptr = file_name_at_cursor(); /* do autowrite if necessary */ if (curbuf->b_changed && curbuf->b_nwindows <= 1 && !p_hid) autowrite(curbuf); if (ptr != NULL) { setpcmark(); stuffReadbuff((char_u *) ":e "); stuffReadbuff(ptr); stuffReadbuff((char_u *) "\n"); free(ptr); } else CLEAROPBEEP; break; /* * "gs": goto sleep */ case 's': while (Prenum1-- && !got_int) { sleep(1); breakcheck(); } break; default: CLEAROPBEEP; break; } break; /* * The end */ case ESC: if (VIsual.lnum) { VIsual.lnum = 0; /* stop Visual */ updateScreen(NOT_VALID); CLEAROP; /* don't beep */ break; } /* Don't drop through and beep if we are canceling a command: */ else if (operator != NOP || opnum || Prenum || yankbuffer) { CLEAROP; /* don't beep */ break; } /* FALLTHROUGH */ default: /* not a known command */ CLEAROPBEEP; break; } /* end of switch on command character */ /* * if we didn't start or finish an operator, reset yankbuffer, unless we * need it later. */ if (!finish_op && !operator && strchr("\"DCYSsXx.", c) == NULL) yankbuffer = 0; /* * If an operation is pending, handle it... */ if ((VIsual.lnum || finish_op) && operator != NOP) { if (operator != YANK && !VIsual.lnum) /* can't redo yank */ { prep_redo(Prenum, opchars[operator - 1], c, nchar); if (c == '/' || c == '?') /* was a search */ { AppendToRedobuff(searchbuff); AppendToRedobuff(NL_STR); } } if (redo_Visual_busy) { curbuf->b_startop = curwin->w_cursor; curwin->w_cursor.lnum += redo_Visual_nlines - 1; switch (redo_Visual_type) { case 'V': VIsual.col = VISUALLINE; break; case Ctrl('V'): Visual_block = TRUE; break; case 'v': if (redo_Visual_nlines <= 1) curwin->w_cursor.col += redo_Visual_col - 1; else curwin->w_cursor.col = redo_Visual_col; break; } if (redo_Visual_col == MAXCOL) { curwin->w_curswant = MAXCOL; coladvance(MAXCOL); } Prenum = redo_Visual_Prenum; if (Prenum == 0) Prenum1 = 1L; else Prenum1 = Prenum; } else if (VIsual.lnum) curbuf->b_startop = VIsual; if (lt(curbuf->b_startop, curwin->w_cursor)) { curbuf->b_endop = curwin->w_cursor; curwin->w_cursor = curbuf->b_startop; } else { curbuf->b_endop = curbuf->b_startop; curbuf->b_startop = curwin->w_cursor; } nlines = curbuf->b_endop.lnum - curbuf->b_startop.lnum + 1; if (VIsual.lnum || redo_Visual_busy) { if (Visual_block) /* block mode */ { startvcol = getvcol(curwin, &(curbuf->b_startop), 2); n = getvcol(curwin, &(curbuf->b_endop), 2); if (n < startvcol) startvcol = (colnr_t)n; /* if '$' was used, get endvcol from longest line */ if (curwin->w_curswant == MAXCOL) { curwin->w_cursor.col = MAXCOL; endvcol = 0; for (curwin->w_cursor.lnum = curbuf->b_startop.lnum; curwin->w_cursor.lnum <= curbuf->b_endop.lnum; ++curwin->w_cursor.lnum) if ((n = getvcol(curwin, &curwin->w_cursor, 3)) > endvcol) endvcol = (colnr_t)n; curwin->w_cursor = curbuf->b_startop; } else if (redo_Visual_busy) endvcol = startvcol + redo_Visual_col - 1; else { endvcol = getvcol(curwin, &(curbuf->b_startop), 3); n = getvcol(curwin, &(curbuf->b_endop), 3); if (n > endvcol) endvcol = (colnr_t)n; } coladvance(startvcol); } /* * prepare to reselect and redo Visual: this is based on the size * of the Visual text */ if (Visual_block) resel_Visual_type = Ctrl('V'); else if (VIsual.col == VISUALLINE) resel_Visual_type = 'V'; else resel_Visual_type = 'v'; if (curwin->w_curswant == MAXCOL) resel_Visual_col = MAXCOL; else if (Visual_block) resel_Visual_col = endvcol - startvcol + 1; else if (nlines > 1) resel_Visual_col = curbuf->b_endop.col; else resel_Visual_col = curbuf->b_endop.col - curbuf->b_startop.col + 1; resel_Visual_nlines = nlines; if (operator != YANK && operator != COLON) /* can't redo yank and : */ { prep_redo(0L, 'v', opchars[operator - 1], NUL); redo_Visual_type = resel_Visual_type; redo_Visual_col = resel_Visual_col; redo_Visual_nlines = resel_Visual_nlines; redo_Visual_Prenum = Prenum; } /* * Mincl defaults to TRUE. * If endop is on a NUL (empty line) mincl becomes FALSE * This makes "d}P" and "v}dP" work the same. */ mincl = TRUE; if (VIsual.col == VISUALLINE) mtype = MLINE; else { mtype = MCHAR; if (*ml_get_pos(&(curbuf->b_endop)) == NUL) mincl = FALSE; } redo_Visual_busy = FALSE; /* * Switch Visual off now, so screen updating does * not show inverted text when the screen is redrawn. * With YANK and sometimes with COLON and FILTER there is no screen * redraw, so it is done here to remove the inverted part. */ VIsual.lnum = 0; if (operator == YANK || operator == COLON || operator == FILTER) updateScreen(NOT_VALID); } else if (operator == LSHIFT || operator == RSHIFT) Prenum1 = 1L; /* if not visual mode: shift one indent */ curwin->w_set_curswant = 1; /* no_op is set when start and end are the same */ no_op = (mtype == MCHAR && !mincl && equal(curbuf->b_startop, curbuf->b_endop)); /* * If the end of an operator is in column one while mtype is MCHAR and mincl * is FALSE, we put endop after the last character in the previous line. * If startop is on or before the first non-blank in the line, the operator * becomes linewise (strange, but that's the way vi does it). */ if (mtype == MCHAR && mincl == FALSE && curbuf->b_endop.col == 0 && nlines > 1) { --nlines; --curbuf->b_endop.lnum; if (inindent()) mtype = MLINE; else { curbuf->b_endop.col = STRLEN(ml_get(curbuf->b_endop.lnum)); if (curbuf->b_endop.col) { --curbuf->b_endop.col; mincl = TRUE; } } } switch (operator) { case LSHIFT: case RSHIFT: doshift(operator, TRUE, (int)Prenum1); modified = TRUE; break; case DELETE: if (!no_op) { dodelete(); modified = TRUE; } break; case YANK: if (!no_op) (void)doyank(FALSE); break; case CHANGE: dochange(); modified = TRUE; command_busy = TRUE; break; case FILTER: bangredo = TRUE; /* dobang() will put cmd in redo buffer */ case INDENT: case COLON: dofilter: sprintf((char *)IObuff, ":%ld,%ld", (long)curbuf->b_startop.lnum, (long)curbuf->b_endop.lnum); stuffReadbuff(IObuff); if (operator != COLON) stuffReadbuff((char_u *)"!"); if (operator == INDENT) { stuffReadbuff(p_ep); stuffReadbuff((char_u *)"\n"); } else if (operator == FORMAT) { stuffReadbuff(p_fp); stuffReadbuff((char_u *)"\n"); } /* docmdline() does the rest */ break; case TILDE: case UPPER: case LOWER: if (!no_op) { dotilde(); modified = TRUE; } break; case FORMAT: if (*p_fp != NUL) goto dofilter; /* use external command */ doformat(); /* use internal function */ modified = TRUE; break; default: CLEAROPBEEP; } operator = NOP; Visual_block = FALSE; yankbuffer = 0; } normal_end: premsg(-1, NUL); if (restart_edit && operator == NOP && VIsual.lnum == 0 && !command_busy && stuff_empty() && yankbuffer == 0) { startinsert(restart_edit, FALSE, 1L); modified = TRUE; } checkpcmark(); /* check if we moved since setting pcmark */ /* * TEMPORARY: update the other windows for the current buffer if modified */ if (modified) { WIN *wp; for (wp = firstwin; wp; wp = wp->w_next) if (wp != curwin && wp->w_buffer == curbuf) { cursor_off(); wp->w_redr_type = NOT_VALID; win_update(wp); } } }
void handle_key_press(char key) { char *tri_code; // Standard key presses... // Default "How Many Cans?" screen if (lcd_state == LCD_STATE_DEFAULT) { // 1 - 9 if (key >= 49 && key <= 57) { write_char(key); cursor_left(1); } } // Admin menu if (lcd_state == LCD_STATE_ADMIN) { if (key == '#') { write_admin_menu(1); } else if (key == '*') { write_admin_menu(-1); } // 0 - 9 if (key >= 48 && key <= 57) { switch (key) { // Exit case '0': lcd_reset(); break; // Restock case '1': // Unlock teh door break; // Enroll case '2': // Enroll break; // Drug deal case '3': // Deduct from user 'drugs' // Open door break; }; } } // Tri codes... // *69 for admin if (tri_code = (char *)get_tri_code()) { if (strcmp(tri_code, "*69") == 0) { clear_screen(); cursor_blink_off(); cursor_off(); write_string("Admin mode...\n* & # to scroll"); admin_line = 0; sleep(2); write_admin_menu(0); lcd_state = LCD_STATE_ADMIN; } } }
void edit_game(FILE *fp) { int quit = 0, m = 0; int x, y, z, a, c, xp, yp; while(!quit && m >= 0) { xp = maze[m].xp, yp = maze[m].yp; clear_screen(); cursor(0, 0); for(y = 0; y < 22; y ++) { cursor(0, y); for(x = 0; x < 80; x ++) { if(x == xp && y == yp) printf("\017"); else if(x == maze[m].xp && y == maze[m].yp) printf("\001"); else { switch(maze[m].sq[x][y].type) { case MAZE_BLANK: printf(" "); break; case MAZE_KEY: printf("\013"); break; /*case MAZE_NOKEY: printf("\372"); break;*/ case MAZE_DOOR: printf("\376"); break; case MAZE_FINISH: printf("\257"); break; default: printf("\333"); break; } } } } cursor_off(); while(!quit) { cursor(0, 0); if(xp > 0) maze[m].sq[xp-1][yp].ex = 1; if(yp > 0) maze[m].sq[xp][yp-1].ex = 1; if(xp < 79) maze[m].sq[xp+1][yp].ex = 1; if(yp < 21) maze[m].sq[xp][yp+1].ex = 1; if(xp > 0 && yp > 0) maze[m].sq[xp-1][yp-1].ex = 1; if(xp > 0 && yp < 21) maze[m].sq[xp-1][yp+1].ex = 1; if(xp < 79 && yp > 0) maze[m].sq[xp+1][yp-1].ex = 1; if(xp < 79 && yp < 21) maze[m].sq[xp+1][yp+1].ex = 1; z = xp-1; if(z < 0) z = 0; for(y = yp-1 < 0 ? 0 : yp-1; y < yp+2 && y < 22; y ++) { cursor(z, y); for(x = z; x < xp+2 && x < 80; x ++) { if(x == xp && y == yp) printf("\017"); else if(x == maze[m].xp && y == maze[m].yp) printf("\001"); else { switch(maze[m].sq[x][y].type) { case MAZE_BLANK: printf(" "); break; case MAZE_KEY: printf("\013"); break; /*case MAZE_NOKEY: printf("\372"); break;*/ case MAZE_DOOR: printf("\376"); break; case MAZE_FINISH: printf("\257"); break; default: printf("\333"); break; } } } } cursor(0, 22); printf("MAZE %c ", m+'A'); switch(maze[m].sq[xp][yp].type) { case MAZE_KEY: printf("Key %c ", maze[m].sq[xp][yp].data < 26 ? maze[m].sq[xp][yp].data + 'A' : maze[m].sq[xp][yp].data + 'a' - 26); break; case MAZE_DOOR: printf("Door %c", maze[m].sq[xp][yp].data < 26 ? maze[m].sq[xp][yp].data + 'A' : maze[m].sq[xp][yp].data + 'a' - 26); break; case MAZE_FINISH: printf("Fin %c ", maze[m].sq[xp][yp].data < 0 ? '>' : maze[m].sq[xp][yp].data + 'A'); break; default: printf(" "); break; } switch((c=getch())) { case 0: /* extended */ switch((c=getch())) { case 72: /* up */ if(yp > 0) yp --; break; case 80: /* down */ if(yp < 21) yp ++; break; case 75: /* left */ if(xp > 0) xp --; break; case 77: /* right */ if(xp < 79) xp ++; break; case 15: /* shift-tab */ if(m > 0) { m --; quit = 1; } break; } break; case 27: quit = 2; break; /* esc */ case ' ': maze[m].sq[xp][yp].type = MAZE_BLANK; break; case '.': maze[m].sq[xp][yp].type = MAZE_WALL; break; case '+': maze[m].sq[xp][yp].type = MAZE_KEY; while(!isalpha(c = getch())) ; maze[m].sq[xp][yp].data = (isupper(c) ? c-'A' : c-'a'+26); break; case '-': maze[m].sq[xp][yp].type = MAZE_DOOR; while(!isalpha(c = getch())) ; maze[m].sq[xp][yp].data = (isupper(c) ? c-'A' : c-'a'+26); break; case '>': maze[m].sq[xp][yp].type = MAZE_FINISH; c = getch(); maze[m].sq[xp][yp].data = (c>='A' && c<='M' ? c-'A' : -1); break; case 's': cursor(maze[m].xp, maze[m].yp); printf(" "); maze[m].xp = xp, maze[m].yp = yp; maze[m].sq[xp][yp].type = MAZE_BLANK; break; case 'l': for(x = 0; x < 80; x ++) { for(y = 0; y < 22; y ++) { if(maze[m].sq[x][y].type == MAZE_DOOR || maze[m].sq[x][y].type == MAZE_KEY) { cursor(x, y); printf("%c", maze[m].sq[x][y].data < 26 ? maze[m].sq[x][y].data + 'A' : maze[m].sq[x][y].data + 'a'-26); } } } getch(); for(x = 0; x < 80; x ++) { for(y = 0; y < 22; y ++) { if(maze[m].sq[x][y].type == MAZE_DOOR) { cursor(x, y); printf("\376"); } else if(maze[m].sq[x][y].type == MAZE_KEY) { cursor(x, y); printf("\013"); } } } break; case '\t': if(m < 13) { m ++; quit = 1; } break; } /*cursor(0, 24); printf("%3i", c);*/ } quit --; } fputs("TMAZE\n", fp); for(z = 0; z < 13; z ++) { for(x = 0; x < 80; x ++) { for(y = 0; y < 22; y ++) { if(maze[z].sq[x][y].type != MAZE_BLANK) x = 81; } } if(x > 80) { putc(z+'A', fp); putc('\n', fp); for(y = 0; y < 22; y ++) { for(a = 79; a >= 0; a --) { if(maze[z].sq[a][y].type != MAZE_BLANK || (maze[z].xp == a && maze[z].yp == y)) break; } for(x = 0; x <= a; x ++) { if(x == maze[z].xp && y == maze[z].yp) putc(':', fp); else switch(maze[z].sq[x][y].type) { case MAZE_BLANK: putc(' ', fp); break; case MAZE_WALL: putc('.', fp); break; case MAZE_KEY: case MAZE_NOKEY: putc('+', fp); putc(maze[z].sq[x][y].data < 26 ? maze[z].sq[x][y].data + 'A' : maze[z].sq[x][y].data + 'a'-26, fp); break; case MAZE_DOOR: putc('-', fp); putc(maze[z].sq[x][y].data < 26 ? maze[z].sq[x][y].data + 'A' : maze[z].sq[x][y].data + 'a'-26, fp); break; case MAZE_FINISH: putc('>', fp); if(maze[z].sq[x][y].data == -1) putc('>', fp); else putc(maze[z].sq[x][y].data + 'A', fp); break; } } putc('\n', fp); } } } cursor_on(); }
void play_game(void) { int quit = 0, key[52], m = 0; int x, y, z, c, xp, yp; while(!quit && m >= 0) { xp = maze[m].xp, yp = maze[m].yp; for(x = 0; x < 52; x ++) key[x] = 0; for(x = 0; x < 80; x ++) { for(y = 0; y < 22; y ++) { maze[m].sq[x][y].ex = 0; } } clear_screen(); cursor(0, 0); for(x = 0; x < 80; x ++) { printf("\260\260\260\260\260\260\260\260\260\260" "\260\260\260\260\260\260\260\260\260\260\260\260"); } cursor_off(); while(!quit) { cursor(0, 0); if(xp > 0) maze[m].sq[xp-1][yp].ex = 1; if(yp > 0) maze[m].sq[xp][yp-1].ex = 1; if(xp < 79) maze[m].sq[xp+1][yp].ex = 1; if(yp < 21) maze[m].sq[xp][yp+1].ex = 1; if(xp > 0 && yp > 0) maze[m].sq[xp-1][yp-1].ex = 1; if(xp > 0 && yp < 21) maze[m].sq[xp-1][yp+1].ex = 1; if(xp < 79 && yp > 0) maze[m].sq[xp+1][yp-1].ex = 1; if(xp < 79 && yp < 21) maze[m].sq[xp+1][yp+1].ex = 1; z = xp-1; if(z < 0) z = 0; for(y = yp-1 < 0 ? 0 : yp-1; y < yp+2 && y < 22; y ++) { cursor(z, y); for(x = z; x < xp+2 && x < 80; x ++) { if(x == xp && y == yp) printf("\017"); else if(maze[m].sq[x][y].ex) { switch(maze[m].sq[x][y].type) { case MAZE_BLANK: printf(" "); break; case MAZE_KEY: printf("\013"); break; case MAZE_NOKEY: printf("\372"); break; case MAZE_DOOR: printf("\376"); break; case MAZE_FINISH: printf("\257"); break; default: printf("\333"); break; } } } } switch((c=getch())) { case 0: /* extended */ switch((c=getch())) { case 72: /* up */ if(yp > 0) { switch(maze[m].sq[xp][yp-1].type) { case MAZE_FINISH: m = maze[m].sq[xp][yp-1].data; quit = 1; break; case MAZE_NOKEY: case MAZE_BLANK: yp --; break; case MAZE_WALL: break; case MAZE_KEY: yp --; key[maze[m].sq[xp][yp].data] = 1; maze[m].sq[xp][yp].type = MAZE_NOKEY; break; case MAZE_DOOR: if(key[maze[m].sq[xp][yp-1].data]) yp --; break; } } break; case 80: /* down */ if(yp < 21) { switch(maze[m].sq[xp][yp+1].type) { case MAZE_FINISH: m = maze[m].sq[xp][yp+1].data; quit = 1; break; case MAZE_NOKEY: case MAZE_BLANK: yp ++; break; case MAZE_WALL: break; case MAZE_KEY: yp ++; key[maze[m].sq[xp][yp].data] = 1; maze[m].sq[xp][yp].type = MAZE_NOKEY; break; case MAZE_DOOR: if(key[maze[m].sq[xp][yp+1].data]) yp ++; break; } } break; case 75: /* left */ if(xp > 0) { switch(maze[m].sq[xp-1][yp].type) { case MAZE_FINISH: m = maze[m].sq[xp-1][yp].data; quit = 1; break; case MAZE_NOKEY: case MAZE_BLANK: xp --; break; case MAZE_WALL: break; case MAZE_KEY: xp --; key[maze[m].sq[xp][yp].data] = 1; maze[m].sq[xp][yp].type = MAZE_NOKEY; break; case MAZE_DOOR: if(key[maze[m].sq[xp-1][yp].data]) xp --; break; } } break; case 77: /* right */ if(xp < 79) { switch(maze[m].sq[xp+1][yp].type) { case MAZE_FINISH: m = maze[m].sq[xp+1][yp].data; quit = 1; break; case MAZE_NOKEY: case MAZE_BLANK: xp ++; break; case MAZE_WALL: break; case MAZE_KEY: xp ++; key[maze[m].sq[xp][yp].data] = 1; maze[m].sq[xp][yp].type = MAZE_NOKEY; break; case MAZE_DOOR: if(key[maze[m].sq[xp+1][yp].data]) xp ++; break; } } break; } break; case 27: quit = 2; break; /* esc */ } /*cursor(0, 24); printf("%3i", c);*/ } quit --; } cursor_on(); }