#include #include #include #include #define ROW_SIZE 16 #define CTRL_KEY(k) ((k) & 0x1f) unsigned char* buffer; long file_size; char* filename; int cursor_pos = 0; int scroll_offset = 0; void load_file(const char* fname) { FILE* f = fopen(fname, "rb"); if (!f) { perror("Nie można otworzyć pliku"); exit(1); } fseek(f, 0, SEEK_END); file_size = ftell(f); rewind(f); buffer = malloc(file_size); fread(buffer, 1, file_size, f); fclose(f); } void save_file() { FILE* f = fopen(filename, "wb"); if (f) { fwrite(buffer, 1, file_size, f); fclose(f); } } void draw_interface() { clear(); int max_y, max_x; getmaxyx(stdscr, max_y, max_x); attron(COLOR_PAIR(1)); mvprintw(0, 0, "HEXED: %s (ROZMIAR: %ld bajtow)", filename, file_size); mvprintw( 1, 0, "^S: Zapisz | ^Q: Wyjscie | Strzalki: Nawigacja | +/-: Zmien wartosc"); mvhline(2, 0, ACS_HLINE, max_x); attroff(COLOR_PAIR(1)); int rows_to_draw = max_y - 4; for (int i = 0; i < rows_to_draw; i++) { int offset = scroll_offset + (i * ROW_SIZE); if (offset >= file_size) break; attron(COLOR_PAIR(1)); mvprintw(3 + i, 0, "%08X: ", offset); attroff(COLOR_PAIR(1)); for (int j = 0; j < ROW_SIZE; j++) { if (offset + j < file_size) { unsigned char val = buffer[offset + j]; int color_pair = (val == 0x00) ? 3 : 2; if (offset + j == cursor_pos) { attron(COLOR_PAIR(4)); printw("%02X ", val); attroff(COLOR_PAIR(4)); } else { attron(COLOR_PAIR(color_pair)); printw("%02X ", val); attroff(COLOR_PAIR(color_pair)); } } else { printw(" "); } } printw("| "); for (int j = 0; j < ROW_SIZE; j++) { if (offset + j < file_size) { unsigned char c = buffer[offset + j]; char ch = (isprint(c)) ? c : '.'; int color_pair = (c == 0x00) ? 3 : 2; if (offset + j == cursor_pos) { attron(COLOR_PAIR(4)); printw("%c", ch); attroff(COLOR_PAIR(4)); } else { attron(COLOR_PAIR(color_pair)); printw("%c", ch); attroff(COLOR_PAIR(color_pair)); } } } } refresh(); } void update_byte(int ch) { int val = -1; if (ch >= '0' && ch <= '9') val = ch - '0'; if (ch >= 'a' && ch <= 'f') val = ch - 'a' + 10; if (ch >= 'A' && ch <= 'F') val = ch - 'A' + 10; if (val != -1) { buffer[cursor_pos] = (buffer[cursor_pos] << 4) | val; } } int main(int argc, char* argv[]) { if (argc < 2) { printf("Uzycie: %s \n", argv[0]); return 1; } filename = argv[1]; load_file(filename); initscr(); start_color(); use_default_colors(); init_pair(1, COLOR_CYAN, -1); init_pair(2, COLOR_WHITE, -1); init_pair(3, COLOR_BLUE, -1); init_pair(4, COLOR_BLACK, COLOR_WHITE); raw(); noecho(); keypad(stdscr, TRUE); curs_set(0); int ch; int max_y, max_x; draw_interface(); int running = 1; while (running) { ch = getch(); getmaxyx(stdscr, max_y, max_x); switch (ch) { case CTRL_KEY('q'): running = 0; break; case KEY_UP: if (cursor_pos >= ROW_SIZE) cursor_pos -= ROW_SIZE; break; case KEY_DOWN: if (cursor_pos + ROW_SIZE < file_size) cursor_pos += ROW_SIZE; break; case KEY_LEFT: if (cursor_pos > 0) cursor_pos--; break; case KEY_RIGHT: if (cursor_pos < file_size - 1) cursor_pos++; break; case '+': buffer[cursor_pos]++; break; case '-': buffer[cursor_pos]--; break; case CTRL_KEY('s'): save_file(); mvprintw(max_y - 1, 0, "ZAPISANO!"); break; case KEY_NPAGE: { int rows = max_y - 4; int jump = rows * ROW_SIZE; if (cursor_pos + jump < file_size) { cursor_pos += jump; } else { cursor_pos = file_size - 1; } } break; case KEY_PPAGE: { int rows = max_y - 4; int jump = rows * ROW_SIZE; if (cursor_pos - jump >= 0) { cursor_pos -= jump; } else { cursor_pos = 0; } } break; default: update_byte(ch); break; } int rows_on_screen = max_y - 4; int cursor_row_start = (cursor_pos / ROW_SIZE) * ROW_SIZE; if (cursor_pos < scroll_offset) { scroll_offset = cursor_row_start; } else if (cursor_pos >= scroll_offset + (rows_on_screen * ROW_SIZE)) { scroll_offset = cursor_row_start - ((rows_on_screen - 1) * ROW_SIZE); if (scroll_offset < 0) scroll_offset = 0; } draw_interface(); } endwin(); free(buffer); return 0; }