void help_display(struct world *mzx_world, char *help, int offs, char *file, char *label) { // Display a help file int pos = offs, old_pos; // Where int key = 0; int t1; char mclick; // allow_help = 0; // Draw screen save_screen(); dialog_fadein(); scroll_edging_ext(mzx_world, 3, 256, 16); // Loop file[0] = label[0] = 0; do { // Display scroll help_frame(mzx_world, help, pos); mclick = 0; update_screen(); update_event_status_delay(); if(get_mouse_press()) { int mouse_x, mouse_y; get_mouse_position(&mouse_x, &mouse_y); // Move to line clicked on if mouse is in scroll, else exit if((mouse_y >= 6) && (mouse_y <= 18) && (mouse_x >= 8) && (mouse_x <= 71)) { mclick = 1; t1 = mouse_y - 12; if(t1 == 0) goto option; //t1<0 = PGUP t1 lines //t1>0 = PGDN t1 lines if(t1 < 0) goto pgup; goto pgdn; } key = IKEY_ESCAPE; } key = get_key(keycode_internal); old_pos = pos; switch(key) { case IKEY_F1: { if(get_alt_status(keycode_internal)) { // Jump to label 072 in MAIN.HLP strcpy(file,"MAIN.HLP"); strcpy(label,"072"); } else { // Jump to label 000 in HELPONHE.HLP strcpy(file, "HELPONHE.HLP"); strcpy(label, "000"); } goto ex; } case IKEY_UP: { // Go back a line (if possible) if(help[pos - 1] == 1) break; // Can't. pos--; // Go to start of this line. do { pos--; } while((help[pos] != '\n') && (help[pos] != 1)); pos++; // Done. break; } case IKEY_DOWN: { // Go forward a line (if possible) while(help[pos] != '\n') pos++; // At end of current. Is there a next line? pos++; if(help[pos] == 0) { // Nope. pos = old_pos; break; } // Yep. Done. break; } case IKEY_RETURN: { option: // Option? if((help[pos] == 255) && ((help[pos + 1] == '>') || (help[pos + 1] == '<'))) { // Yep! pos++; if(help[pos] == '<') { // Get file and label and exit t1 = 0; pos++; do { pos++; file[t1] = help[pos]; t1++; } while(help[pos] != ':'); file[t1 - 1] = 0; strcpy(label, help + pos + 1); goto ex; } // Get label and jump strcpy(label, help + pos + 2); // Search backwards for a 1 do { pos--; } while(help[pos] != 1); // Search for label OR a \n followed by a \0 do { pos++; if(help[pos] == 255) if(help[pos + 1] == ':') if(!strcmp(help + pos + 3, label)) // pos is correct! goto labdone; if(help[pos] == '\n') if(help[pos + 1] == 0) break; } while(1); } // If there WAS an option, any existing label was found. labdone: break; } case IKEY_PAGEDOWN: { for(t1 = 6; t1 > 0; t1--) { pgdn: // Go forward a line (if possible) old_pos = pos; while(help[pos] != '\n') pos++; // At end of current. Is there a next line? pos++; if(help[pos] == 0) { // Nope. pos = old_pos; break; } // Yep. Done. } if(mclick) goto option; break; } case IKEY_PAGEUP: { for(t1 = -6; t1 < 0; t1++) { pgup: // Go back a line (if possible) if(help[pos - 1] == 1) break; // Can't. pos--; // Go to start of this line. do { pos--; } while((help[pos] != '\n') && (help[pos] != 1)); pos++; // Done. } if(mclick) goto option; break; } case IKEY_HOME: { // FIXME - :( t1 = -30000; goto pgup; } case IKEY_END: { t1 = 30000; goto pgdn; } default: { break; } } } while(key != IKEY_ESCAPE); // Restore screen and exit ex: dialog_fadeout(); restore_screen(); }
void scroll_edit(struct world *mzx_world, struct scroll *scroll, int type) { // Important status vars (insert kept in intake.cpp) unsigned int pos = 1, old_pos; // Where IN scroll? int currx = 0; // X position in line int key; // Key returned by intake() int t1, t2 = -1, t3; char *where; // Where scroll is char line[80]; // For editing int scroll_base_color = mzx_world->scroll_base_color; bool editing = (type == 2); // Draw screen save_screen(); dialog_fadein(); if(editing) scroll_edging_ext(mzx_world, type, 256, 16); else scroll_edging_ext(mzx_world, type, 0, 16); // Loop where = scroll->mesg; do { // If the user wants to mask, and we're in the editor.. bool mask = mzx_world->conf.mask_midchars && editing; // Display scroll scroll_frame(mzx_world, scroll, pos, mask); update_screen(); if(editing) { // Figure length for(t1 = 0; t1 < 80; t1++) { if(where[pos + t1] == '\n') break; } // t1 == length // Edit line where[pos + t1] = 0; strcpy(line, where + pos); where[pos + t1] = '\n'; key = intake(mzx_world, line, 64, 8, 12, scroll_base_color, 2, 0, &currx, 0, NULL); // Modify scroll to hold new line (give errors here) t2 = (int)strlen(line); // Get length of NEW line // Resize and move t3 = scroll->mesg_size; if(t2 - t1 > 0) { reallocate_scroll(scroll, t3 + t2 - t1); where = scroll->mesg; memmove(where + pos + t2, where + pos + t1, t3 - pos - t1); } else if(t2 - t1 < 0) { memmove(where + pos + t2, where + pos + t1, t3 - pos - t1); reallocate_scroll(scroll, t3 + t2 - t1); where = scroll->mesg; } // Copy in new line strcpy(where + pos, line); where[pos + t2] = '\n'; } else { update_event_status_delay(); key = get_key(keycode_internal); } old_pos = pos; if(get_mouse_press() || (key == -1)) { int mouse_x, mouse_y; get_mouse_position(&mouse_x, &mouse_y); if((mouse_y >= 6) && (mouse_y <= 18) && (mouse_x >= 8) && (mouse_x <= 71)) { t1 = mouse_y - 12; if(t1) { if(t1 < 0) goto pgdn; else goto pgup; } } key = IKEY_ESCAPE; } switch(key) { case IKEY_UP: { // Go back a line (if possible) if(where[pos - 1] == 1) break; // Can't. pos--; // Go to start of this line. do { pos--; } while((where[pos] != '\n') && (where[pos] != 1)); pos++; // Done. break; } case IKEY_DOWN: { // Go forward a line (if possible) while(where[pos] != '\n') pos++; // At end of current. Is there a next line? pos++; if(where[pos] == 0) { // Nope. pos = old_pos; break; } // Yep. Done. break; } case IKEY_RETURN: { if(type < 2) { key = IKEY_ESCAPE; } else { // Add in new line below. Need only add one byte. t3 = scroll->mesg_size; reallocate_scroll(scroll, t3 + 1); where = scroll->mesg; // Move all at pos + currx up a space memmove(where + pos + currx + 1, where + pos + currx, t3 - pos - currx); // Insert a \n where[pos + currx] = '\n'; // Change pos and currx pos = pos + currx + 1; currx = 0; scroll->num_lines++; } break; } case IKEY_BACKSPACE: { if(type < 2) break; // We are at the start of the current line and we are trying to // append it to the end of the previous line. First, remember // the size of the current line is in t2. Now we go back a line, // if there is one. if(where[pos - 1] == 1) break; // Nope. pos--; // Go to start of this line, COUNTING CHARACTERS. t1 = 0; do { pos--; t1++; } while((where[pos] != '\n') && (where[pos] != 1)); // pos is at one before the start of this line. WHO CARES!? :) // Now we have to see if the size, t2, is over 64 characters. // t2 + t1 is currently one too many so check for >65 for error. if((t2 + t1) > 65) { pos = old_pos; break; // Too long. Reset position. } // OKAY! Just copy backwards over the \n in the middle to // append... t3 = scroll->mesg_size; memmove(where + (old_pos - 1), where + old_pos, t3 - (old_pos + 1)); // ...and reallocate to one space less! reallocate_scroll(scroll, t3 - 1); where = scroll->mesg; // pos is one before this start. Fix to the start of this new // line. Set currx to the length of the old line this was. pos++; currx = (int)t1 - 1; scroll->num_lines--; // FIXME - total hack! scroll->mesg[scroll->mesg_size - 1] = 0; // Done. break; } case IKEY_PAGEDOWN: { for(t1 = 6; t1 > 0; t1--) { pgdn: // Go forward a line (if possible) old_pos = pos; while(where[pos] != '\n') pos++; // At end of current. Is there a next line? pos++; if(where[pos] == 0) { // Nope. pos = old_pos; break; } // Yep. Done. } break; } case IKEY_PAGEUP: { for(t1 = -6; t1 < 0; t1++) { pgup: // Go back a line (if possible) if(where[pos - 1] == 1) break; // Can't. pos--; // Go to start of this line. do { pos--; } while((where[pos] != '\n') && (where[pos] != 1)); pos++; // Done. } break; } case IKEY_HOME: { // FIXME - This is so dirty. Please replace it. t1 = -30000; goto pgup; } case IKEY_END: { // FIXME - See above. t1 = 30000; goto pgdn; } default: case IKEY_ESCAPE: case 0: break; } // Continue? } while(key != IKEY_ESCAPE); // Restore screen and exit restore_screen(); dialog_fadeout(); }
void wait_for_mouse_release(Uint32 mouse_button) { while(get_mouse_status()) update_event_status_delay(); }
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; }
void wait_for_key_release(Uint32 index) { while(get_key_status(keycode_internal, index) >= 1) update_event_status_delay(); }