From 8461e5ebea6e899eb0643f34ff03d7797d1441bf Mon Sep 17 00:00:00 2001 From: tslil clingman Date: Thu, 21 Jan 2021 20:46:28 -0500 Subject: Starting work on LCD library --- do_buildroot.sh | 4 ++-- include/lcdlib.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/lcdlib.h | 19 +++++++++++++++ src/ct1986.c | 68 +++++++++++++++++++++-------------------------------- 4 files changed, 118 insertions(+), 44 deletions(-) create mode 100644 include/lcdlib.c create mode 100644 include/lcdlib.h diff --git a/do_buildroot.sh b/do_buildroot.sh index 1d26106..40c3f0b 100755 --- a/do_buildroot.sh +++ b/do_buildroot.sh @@ -7,8 +7,8 @@ overlay="$board/rootfs_overlay/" # Build configuration cp resources/buildroot.config "$BR/.config" -# resources/linux.config -cp resources/{post-build,ct1986}.sh resources/genimage-raspberrypi0.cfg resources/busybox.config "$board" +#cp resources/linux.config resources/busybox.config "$board" # Causes recompile +cp resources/{post-build,ct1986}.sh resources/genimage-raspberrypi0.cfg "$board" # Overlay filesystem dirs="/usr/bin" diff --git a/include/lcdlib.c b/include/lcdlib.c new file mode 100644 index 0000000..a22a1e2 --- /dev/null +++ b/include/lcdlib.c @@ -0,0 +1,71 @@ +#include "lcdlib.h" + +// =================================================================== +// Globals +// =================================================================== + +static char previous_lines[LCD_HEIGHT][LCD_WIDTH+1]; +static FILE *lcd = NULL; +static int line_idx; + +static const char* esc = "\x1B[L"; + +int +lcd_begin(void) { + lcd = fopen("/dev/lcd", "w"); + if (lcd == NULL) return EXIT_FAILURE; + fprintf(lcd, "%sB", esc); + fflush(lcd); + lcd_clear(); + return EXIT_SUCCESS; +} + +void +lcd_end(void) { + fclose(lcd); +} + +void +lcd_clear(void) { + line_idx = 0; + for (int y = 0; y + 1 < LCD_HEIGHT; y++) { + fprintf(lcd, "%sy%dx0;%sk", esc, y, esc); + previous_lines[y][0] = 0; + } + fflush(lcd); +} + +void +lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line) { + if (mode == L_SCROLL && line_idx == LCD_HEIGHT) { + // If we're at the bottom, ``shift'' everything up + for (int y = 1; y < LCD_HEIGHT; y++) { + // Go to the start of row y, clear the line, and print the + // previous string there + fprintf(lcd, "%sy%dx0;%sk%s", esc, y-1, esc, previous_lines[y]); + // Overwrite the stored previous line with the next + strncpy(previous_lines[y-1], previous_lines[y], 16); + } + line_idx--; + } + // Go to the correct line, clear it, and write the input. + fprintf(lcd, "%sy%dx0;%sk%s", esc, line_idx, esc, line); + fflush(lcd); + // Store this line, null-terminate! + strncpy(previous_lines[line_idx], line, 16); + previous_lines[line_idx][16] = 0; + if (mode == L_SCROLL && line_idx < LCD_HEIGHT) line_idx++; +} + +void +lcd_printf_line(const enum LCD_WRITE_MODE mode, + const char *format, ...) { + char buf[16]; + + va_list(args); + va_start(args, format); + vsnprintf(buf, 16, format, args); + va_end(args); + + lcd_put_line(mode, buf); +} diff --git a/include/lcdlib.h b/include/lcdlib.h new file mode 100644 index 0000000..fd28a0e --- /dev/null +++ b/include/lcdlib.h @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +#define LCD_WIDTH 16 +#define LCD_HEIGHT 2 + +enum LCD_WRITE_MODE { L_OVERWRITE, L_SCROLL }; + +int lcd_begin(void); +void lcd_end(void); +void lcd_clear(void); + +void lcd_put_line(const enum LCD_WRITE_MODE mode, + const char *line); + +void lcd_printf_line(const enum LCD_WRITE_MODE mode, + const char *format, ...); diff --git a/src/ct1986.c b/src/ct1986.c index f697877..273fd98 100644 --- a/src/ct1986.c +++ b/src/ct1986.c @@ -1,22 +1,13 @@ #include -#include #include #include #include +#include -const char* esc = "\x1B[L"; - -FILE *lcd = NULL; static char *gamelog = 0; static int human; -static void -write_line(const char *line) { - fprintf(lcd, "%s\n", line); - fflush(lcd); -} - static void append_to_gamelog(const char *line, const uint8_t win_line) { // I _could_ dynamically compute the size but ... don't let @@ -45,8 +36,7 @@ static void end_game(char *line, char *win) { append_to_gamelog(line, 0); append_to_gamelog(win, 1); - fprintf(lcd, "Game over: %s\n", win); - fflush(lcd); + lcd_printf_line(L_SCROLL, "Game over: %s", win); } static int @@ -55,9 +45,9 @@ handle_turn(char *line) { uint8_t new_win = (won == 0xFF); switch (do_ptn(line)) { // Errors - case PTN_INVALID: { write_line("Invalid PTN."); break; } - case ACT_ILLEGAL: { write_line("Illegal ply."); break; } - case ACT_OVERFLOW: { write_line("Overflow."); break; } + case PTN_INVALID: { lcd_put_line(L_SCROLL, "Invalid PTN."); break; } + case ACT_ILLEGAL: { lcd_put_line(L_SCROLL, "Illegal ply."); break; } + case ACT_OVERFLOW: { lcd_put_line(L_SCROLL, "Overflow."); break; } // Game has ended case GAME_END: { // Did it end this turn? @@ -71,7 +61,7 @@ handle_turn(char *line) { } return EXIT_SUCCESS; } else { - write_line("Game over."); + lcd_put_line(L_SCROLL, "Game over."); break; } } @@ -87,7 +77,7 @@ handle_turn(char *line) { static void new_game(uint8_t size) { reset_state(size); - write_line("New 5x5 game."); + lcd_put_line(L_SCROLL, "New 5x5 game."); if (gamelog) gamelog = realloc(gamelog, sizeof(char)); else gamelog = malloc(sizeof(char)); gamelog[0] = 0; @@ -95,34 +85,31 @@ new_game(uint8_t size) { // Set up output function for negamax_cnn1986 static uint8_t perc; + inline void negamax_cnn1986_display_progress(const uint8_t depth) { if (depth == 0) { perc++; - // back four spaces and clear line, followed by perc% - fprintf(lcd, "%sl%sl%sl%sl%sk%3d%%", - esc, esc, esc, esc, esc, - perc*4); - fflush(lcd); + lcd_printf_line(L_OVERWRITE, "Computing: %d%%", perc*4); } } static int negamax_cnn1986_turn() { // Prepare progress bar - fputs("Computing: ", lcd); fflush(lcd); + lcd_put_line(L_SCROLL, "Computing: 0%"); // Run the minimax perc = 0; float minimax = negamax_cnn1986_generate(); - fputc('\n', lcd); fflush(lcd); // Failed to find a move? if (minimax <= -infty) { - fprintf(lcd, "%s concedes!\n", (ply & 1) ? "Black" : "White"); + lcd_printf_line(L_SCROLL, "%s concedes!", + (ply & 1) ? "Black" : "White"); return EXIT_FAILURE; } else { - fprintf(lcd, "%s: %s\n", - (ply & 1) ? "Black" : "White", - negamax_cnn1986_ptn); + lcd_printf_line(L_SCROLL, "%s: %s", + (ply & 1) ? "Black" : "White", + negamax_cnn1986_ptn); handle_turn(negamax_cnn1986_ptn); return EXIT_SUCCESS; } @@ -130,7 +117,7 @@ negamax_cnn1986_turn() { static void do_game_log(void) { - fputs(gamelog, lcd); + lcd_put_line(L_SCROLL, "Not implemented."); } static int @@ -138,14 +125,14 @@ input_is_not_turn(const char *line) { switch (line[0]) { case 'l': { do_game_log(); break; } case 'n': { new_game(5); break; } - case 'd': { + case 's': { negamax_cnn1986_search_depth = line[1] - '0'; - fprintf(lcd, "Search depth: %d\n", negamax_cnn1986_search_depth); - fflush(lcd); + lcd_printf_line(L_SCROLL, "Search depth: %d", + negamax_cnn1986_search_depth); break; } - case 'b': { human = 1; new_game(5); break; } - case 'w': { human = 0; new_game(5); break; } + case 'B': { human = 1; new_game(5); break; } + case 'W': { human = 0; new_game(5); break; } default: return EXIT_FAILURE; } return EXIT_SUCCESS; @@ -156,11 +143,8 @@ main(int argc, char **argv) { (void)(argc); (void)(argv); - lcd = fopen("/dev/lcd", "w"); - if (lcd == NULL) return EXIT_FAILURE; - - fprintf(lcd, "%sB", esc); - fflush(lcd); + if (lcd_begin() != EXIT_SUCCESS) + return EXIT_FAILURE; human = 0; negamax_cnn1986_search_depth = 3; @@ -172,8 +156,8 @@ main(int argc, char **argv) { for (int playing = 1; playing;) { while (human == 0) { - if (ply & 1) write_line("Black: "); - else write_line("White: "); + if (ply & 1) lcd_put_line(L_SCROLL, "Black: "); + else lcd_put_line(L_SCROLL, "White: "); read = getline(&line, &alloc_size, stdin); if (read > 0) { line[read - 1] = 0; @@ -194,6 +178,6 @@ main(int argc, char **argv) { } } - fclose(lcd); + lcd_end(); return EXIT_SUCCESS; } -- cgit v1.2.3