forked from snapshot112/minigame-menu
188 lines
4.2 KiB
C
188 lines
4.2 KiB
C
/*
|
|
* Created by snapshot112 on 15/10/2025
|
|
*/
|
|
|
|
#include "minigame_menu.h"
|
|
|
|
#include <ncurses.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "../../engine/grid_game_engine.h"
|
|
#include "../manual/manual.h"
|
|
#include "../maze-runner/maze_runner.h"
|
|
#include "../minesweeper/minesweeper.h"
|
|
#include "../snake/snake.h"
|
|
|
|
#define AMOUNT_OF_MENU_OPTIONS 5
|
|
|
|
typedef enum {
|
|
GAME_MANUAL = 0,
|
|
GAME_MAZE_RUNNER = 1,
|
|
GAME_SNAKE = 2,
|
|
GAME_MINESWEEPER = 3,
|
|
GAME_QUIT = 4,
|
|
} game;
|
|
|
|
static game SELECTED_GAME = GAME_MANUAL;
|
|
static int OFFSET_Y = 5;
|
|
static int OFFSET_X = 5;
|
|
|
|
/*
|
|
* Launch a game from the menu.
|
|
*
|
|
* Input:
|
|
* menu: A pointer to the menu grid.
|
|
* game: The game you want to launch.
|
|
*/
|
|
static void launch_game(const game game) {
|
|
switch (game) {
|
|
case GAME_MANUAL:
|
|
manual((coordinate){0,0});
|
|
break;
|
|
case GAME_MAZE_RUNNER:
|
|
maze_runner();
|
|
break;
|
|
case GAME_SNAKE:
|
|
snake();
|
|
break;
|
|
case GAME_MINESWEEPER:
|
|
minesweeper();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Highlight a valid menu option.
|
|
*
|
|
* Input:
|
|
* menu: A pointer to the menu grid.
|
|
* target: The menu option to highlight.
|
|
* offset_x: The x offset of the menu.
|
|
* offset_y: The y offset of the menu.
|
|
*
|
|
* Side effects:
|
|
* If a valid menu option is provided: It will be highlighted in green.
|
|
* If an invalid menu option is provided: Nothing happens
|
|
*/
|
|
static void menu_highlight(const grid *menu) {
|
|
switch (SELECTED_GAME) {
|
|
case GAME_MANUAL:
|
|
case GAME_MAZE_RUNNER:
|
|
case GAME_SNAKE:
|
|
case GAME_MINESWEEPER:
|
|
case GAME_QUIT:
|
|
attron(COLOR_PAIR(GREEN));
|
|
|
|
char* row = grid_fetch_row(menu, SELECTED_GAME);
|
|
mvprintw(OFFSET_Y + (int)SELECTED_GAME, OFFSET_X, "%s", row);
|
|
free(row);
|
|
|
|
attroff(COLOR_PAIR(GREEN));
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Show the menu screen.
|
|
*
|
|
* Input:
|
|
* menu: A pointer to the menu grid.
|
|
* default_selection: The starting selection in the menu.
|
|
* offset_x: The x offset of the menu.
|
|
* offset_y: The y offset of the menu.
|
|
*
|
|
* Side Effects:
|
|
* Displays the menu
|
|
*/
|
|
static void show_menu(const grid *menu) {
|
|
erase();
|
|
show_grid_on_offset(menu, OFFSET_X, OFFSET_Y);
|
|
menu_highlight(menu);
|
|
refresh();
|
|
}
|
|
|
|
/*
|
|
* Select the game on a location determined by a given offset.
|
|
* Negative values go up and positive values go down.
|
|
* Out of bounds selections loop around.
|
|
*
|
|
* Input:
|
|
* selected_game: The currently selected game.
|
|
* offset: The amount offset the current selection by.
|
|
*
|
|
* Side effect:
|
|
* The game on the location of the given offset will be selected.
|
|
*/
|
|
static void menu_move(const int offset) {
|
|
SELECTED_GAME = modulo(SELECTED_GAME + offset, AMOUNT_OF_MENU_OPTIONS);
|
|
}
|
|
|
|
/*
|
|
* Navigate through the menu.
|
|
*
|
|
* Input:
|
|
* menu: A pointer to the menu grid.
|
|
*
|
|
* Output: A code that reflects the current menu state.
|
|
* 0: Continue running.
|
|
* 1: Exit the menu.
|
|
*
|
|
*
|
|
* Side Effect:
|
|
* Changes the SELECTED_GAME as needed and launches selected games on select.
|
|
*/
|
|
static int navigate_menu(void) {
|
|
switch (getch()) {
|
|
case KEY_UP:
|
|
case 'w':
|
|
case 'W':
|
|
menu_move(-1);
|
|
break;
|
|
case KEY_DOWN:
|
|
case 's':
|
|
case 'S':
|
|
menu_move(1);
|
|
break;
|
|
case KEY_ENTER:
|
|
case '\n':
|
|
case 'f':
|
|
case 'F':
|
|
case ' ':
|
|
if (SELECTED_GAME == GAME_QUIT) {
|
|
return 1;
|
|
}
|
|
launch_game(SELECTED_GAME);
|
|
break;
|
|
case KEY_BACKSPACE:
|
|
case KEY_ESCAPE:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Create the menu grid.
|
|
*
|
|
* Output:
|
|
* A pointer to the menu grid.
|
|
*/
|
|
static grid *initialize_menu(void) {
|
|
char menu[] = "How to play\n"
|
|
"Maze Runner\n"
|
|
" Snake \n"
|
|
"Minesweeper\n"
|
|
" Leave \n";
|
|
grid *rp = grid_create_from_string(menu);
|
|
return rp;
|
|
}
|
|
|
|
void minigame_menu(void) {
|
|
grid *menu = initialize_menu();
|
|
while (true) {
|
|
if (navigate_menu() == 1) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
grid_cleanup(menu);
|
|
}
|