Commit f6cdb877 authored by Chris's avatar Chris
Browse files

prototyped an interactive menu (Linux)

parent 8252f97e
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <termios.h> // for registering raw keypresses, as in menus
#include <unistd.h> // for STDIN_FILENO, used with termios
#include "dicelogic.h"
#include "utils.h"

@@ -18,12 +20,96 @@ int main(void) {
	clear_screen();

	printf("yaht.c\n");
	printf("\n\n\n"); // new menu would erase game name otherwise

	// set terminal to raw mode for registering keypresses without need to press Enter
	struct termios old_terminal_configuration, new_terminal_configuration;
	tcgetattr(STDIN_FILENO, &old_terminal_configuration);
	new_terminal_configuration = old_terminal_configuration;
	new_terminal_configuration.c_lflag &= ~ICANON & ~ECHO & ~ISIG; // disables canonical input, echo, signals
	tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal_configuration); // apply settings to terminal

	typedef struct {
		char *title;

	} menu_item;

	const unsigned int num_menu_items = 2; // lowercase because this will be calculated in more dynamic code
	menu_item items[num_menu_items];
	items[0].title = "New game";
	items[1].title = "Exit";
	int choice = -1;
	unsigned int hovered_choice = 0;
	// menu logic! TODO make this cross platform (play nice with Windows...)
	do {
		// return cursor to menu position
		for (int i = 0; i < num_menu_items; i++) {
			printf("\033[A"); // move cursor up one line
			printf("\033[2K"); // clear entire line
		}

		// print menu items, showing selection
		for (int i = 0; i < num_menu_items; i++) {
			if (i == hovered_choice) {
				printf("> ");
			}
			printf("%s\n", items[i].title);
		}
		char key_pressed = (char)getchar(); // with terminal settings above, this will no longer wait for Enter key; note that Enter key is handled with \n case

		// handle arrow keys todo fix this
		// if (key_pressed == '\033') {
		// 	char which_arrow = (char)getchar();
		// 	switch (which_arrow) {
		// 	case 'B':
		// 		key_pressed = 'j';
		// 		break;
		// 	case 'A':
		// 		key_pressed = 'k';
		// 		break;
		// 	default:
		// 		break;
		// 	}
		// }

		switch (key_pressed) {
		case 'j':
		case 'J':
		case 's':
		case 'S':
			if (hovered_choice < num_menu_items - 1) {
				hovered_choice++;
			}
			break;
		case 'k':
		case 'K':
		case 'w':
		case 'W':
			if (hovered_choice > 0) {
				hovered_choice--;
			}
			break;
		case '\n':
			choice = (int)hovered_choice;
			break;
		default:
			break;
		}
	} while (choice == -1);

	// un-hold all dice
	clear_held_values(&ctx);

	// do_demo_dice_rolls(&ctx, next_roll); // uncomment if you want to see a little demo

	switch (choice) {
		case 0: // new game
			do_demo_dice_rolls(&ctx, next_roll);
			break;
	default:
		break;
	}

	fclose(ctx.random_device_fd);
	return 0;
}