aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-01-21 20:46:28 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit8461e5ebea6e899eb0643f34ff03d7797d1441bf (patch)
tree38518e28192a113dee1ef4821247a0a2ca3c8cc1
parente54f496ce4acab029d95506736539c7f296cbbc8 (diff)
Starting work on LCD library
-rwxr-xr-xdo_buildroot.sh4
-rw-r--r--include/lcdlib.c71
-rw-r--r--include/lcdlib.h19
-rw-r--r--src/ct1986.c68
4 files changed, 118 insertions, 44 deletions
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 <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#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,23 +1,14 @@
#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
#include <tak.h>
#include <negamax_cnn1986.h>
+#include <lcdlib.h>
-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
// `perfect' be the enemy of `good' ?
@@ -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;
}