Mid menu coding

This commit is contained in:
2024-10-07 09:49:22 -05:00
parent a7dc7fdcf8
commit 86feb7e56a
10 changed files with 392 additions and 8 deletions

View File

@ -6,11 +6,11 @@
"tiles": [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1,
1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 2, 2, 2, 1,
1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 2, 2, 2, 1, 1,
1, 1, 1, 1, 4, 4, 4, 4, 4, 1, 1, 1, 2, 2, 1, 1,
1, 1, 1, 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

View File

@ -36,4 +36,5 @@ void drawStateOverworld() {
// Draw UI
drawUITextbox();
drawUITestMenu();
}

View File

@ -8,9 +8,10 @@
#include "drawui.h"
#include "drawshape.h"
#include "assert/assert.h"
#include "ui/textbox.h"
#include "game/time.h"
#include "display/draw/drawtext.h"
#include "ui/textbox.h"
#include "ui/testmenu.h"
void drawUIBox(
const uint16_t x,
@ -58,6 +59,69 @@ void drawUIBox(
drawBox(x + 1, y + 1, width - 2, height - 2, ' ', COLOR_BLACK);
}
void drawUIMenu(
const menu_t *menu,
const uint16_t x,
const uint16_t y,
const uint16_t width,
const char_t* strings[],
const int16_t stringCount,
const uint8_t cursorColor,
const uint8_t textColor
) {
assertTrue(menu, "Menu cannot be NULL.");
assertTrue(strings, "Strings cannot be NULL.");
assertTrue(stringCount > 0, "String count must be greater than 0.");
assertTrue(menu->rows > 0, "Rows must be greater than 0.");
assertTrue(menu->columns > 0, "Columns must be greater than 0.");
assertTrue(width*2 > menu->columns, "Width must be greater than columns.");
uint16_t stringWidth = (width / menu->columns) + 1;// +1 for cursor and padding
// Draw the menu
for(uint16_t row = 0; row < menu->rows; row++) {
for(uint16_t col = 0; col < menu->columns; col++) {
uint16_t index = (row * menu->columns) + col;
if(index >= stringCount) break;
drawText(
strings[index],
-1,
x + (col * stringWidth) + 1,
y + row,
textColor
);
}
}
// Draw the cursor
size_t i = (x + (menu->x * stringWidth)) + ((y + menu->y) * FRAME_WIDTH);
FRAME_BUFFER[i] = '>';
FRAME_COLOR[i] = cursorColor;
}
void drawUIMenuBox(
const menu_t *menu,
const uint16_t x,
const uint16_t y,
const uint16_t width,
const uint16_t height,
const char_t* strings[],
const int16_t stringCount,
const uint8_t cursorColor,
const uint8_t textColor,
const uint8_t boxColor
) {
drawUIBox(x, y, width, height, boxColor, true);
// drawUIMenu(
// menu,
// x + 1, y + 1, width - 2,
// strings, stringCount,
// cursorColor, textColor
// );
}
void drawUITextbox() {
if(!textboxIsOpen()) return;
@ -92,4 +156,47 @@ void drawUITextbox() {
int32_t blink = (int32_t)(TIME.time * DRAW_UI_TEXTBOX_BLINKS_PER_SECOND) % 2;
FRAME_BUFFER[DRAW_UI_TEXTBOX_CURSOR_POS + 1] = blink ? '>' : ' ';
FRAME_BUFFER[DRAW_UI_TEXTBOX_CURSOR_POS + 2] = blink ? ' ' : '>';
}
void drawUITestMenu() {
const char_t* strings[] = {
"Option 1",
"Option 2",
"Option 3",
"Option 4",
"Option 5",
"Option 6",
"Option 7",
"Option 8",
"Option 9",
"Option 10",
"Option 11",
"Option 12",
"Option 13",
"Option 14",
"Option 15",
"Option 16",
"Option 17",
"Option 18",
"Option 19",
"Option 20",
"Option 21",
"Option 22",
"Option 23",
"Option 24",
"Option 25",
"Option 26",
"Option 27",
"Option 28",
"Option 29",
"Option 30"
};
drawUIMenuBox(
&TEST_MENU.menu,
0, 0,
FRAME_WIDTH, 5,
strings, sizeof(strings) / sizeof(char_t*),
COLOR_CYAN, COLOR_WHITE, COLOR_MAGENTA
);
}

View File

@ -7,6 +7,7 @@
#pragma once
#include "display/frame.h"
#include "ui/menu.h"
#define DRAW_UI_TEXTBOX_WIDTH FRAME_WIDTH
#define DRAW_UI_TEXTBOX_HEIGHT 8
@ -32,7 +33,63 @@ void drawUIBox(
const bool_t fill
);
/**
* Draws a UI menu to the frame buffer.
*
* @param menu The menu to draw.
* @param x The x position to draw the menu.
* @param y The y position to draw the menu.
* @param width The width of the menu.
* @param strings The strings to draw in the menu.
* @param stringCount The number of strings in the menu.
* @param cursorColor The color of the cursor.
* @param textColor The color of the text.
*/
void drawUIMenu(
const menu_t *menu,
const uint16_t x,
const uint16_t y,
const uint16_t width,
const char_t* strings[],
const int16_t stringCount,
const uint8_t cursorColor,
const uint8_t textColor
);
/**
* Draws a UI menu box to the frame buffer.
*
* @param menu The menu to draw.
* @param x The x position to draw the menu.
* @param y The y position to draw the menu.
* @param width The width of the menu.
* @param height The height of the menu.
* @param strings The strings to draw in the menu.
* @param stringCount The number of strings in the menu.
* @param cursorColor The color of the cursor.
* @param textColor The color of the text.
* @param boxColor The color of the box.
*/
void drawUIMenuBox(
const menu_t *menu,
const uint16_t x,
const uint16_t y,
const uint16_t width,
const uint16_t height,
const char_t* strings[],
const int16_t stringCount,
const uint8_t cursorColor,
const uint8_t textColor,
const uint8_t boxColor
);
/**
* Draws the UI textbox to the frame buffer.
*/
void drawUITextbox();
void drawUITextbox();
/**
* Draws the UI test menu to the frame buffer.
*/
void drawUITestMenu();

View File

@ -9,9 +9,10 @@
#include "game/time.h"
#include "input.h"
#include "display/display.h"
#include "ui/textbox.h"
#include "asset/asset.h"
#include "asset/assetmap.h"
#include "ui/textbox.h"
#include "ui/testmenu.h"
game_t GAME;
@ -22,7 +23,9 @@ void gameInit() {
inputInit();
displayInit();
assetInit();
textboxInit();
testMenuInit();
GAME.mapNext = MAP_LIST_TEST;
GAME.state = GAME_STATE_MAP_CHANGE;
@ -39,6 +42,7 @@ gameupdateresult_t gameUpdate(const float_t delta) {
case GAME_STATE_OVERWORLD:
textboxUpdate();
testMenuUpdate();
if(GAME.currentMap) mapUpdate(GAME.currentMap);
if(inputWasPressed(INPUT_BIND_PAUSE)) GAME.state = GAME_STATE_PAUSED;
break;

View File

@ -8,5 +8,7 @@
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
menu.c
textbox.c
testmenu.c
)

112
src/dawn/ui/menu.c Normal file
View File

@ -0,0 +1,112 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "menu.h"
#include "assert/assert.h"
#include "input.h"
#include "game/time.h"
void menuInit(menu_t *menu, const uint16_t rows, const uint16_t columns) {
assertNotNull(menu, "Menu cannot be NULL.");
assertTrue(rows > 0, "Rows must be greater than 0.");
assertTrue(columns > 0, "Columns must be greater than 0.");
memset(menu, 0, sizeof(menu_t));
menu->rows = rows;
menu->columns = columns;
}
void menuUpdate(menu_t *menu) {
if(inputWasPressed(INPUT_BIND_UP)) {
menu->repeatHeld = 0.0f;
return menuPositionMove(menu, MENU_DIRECTION_UP);
} else if(inputWasPressed(INPUT_BIND_DOWN)) {
menu->repeatHeld = 0.0f;
return menuPositionMove(menu, MENU_DIRECTION_DOWN);
} else if(inputWasPressed(INPUT_BIND_LEFT)) {
menu->repeatHeld = 0.0f;
return menuPositionMove(menu, MENU_DIRECTION_LEFT);
} else if(inputWasPressed(INPUT_BIND_RIGHT)) {
menu->repeatHeld = 0.0f;
return menuPositionMove(menu, MENU_DIRECTION_RIGHT);
}
// Handle repeat
if(inputIsDown(INPUT_BIND_DOWN)) {
menu->repeatHeld += TIME.delta;
if(menu->repeatHeld >= MENU_HELD_TIME_INITIAL) {
menu->repeatHeld = (MENU_HELD_TIME_INITIAL - MENU_HELD_TIME_REPEAT);
menuPositionMove(menu, MENU_DIRECTION_DOWN);
}
} else if(inputIsDown(INPUT_BIND_UP)) {
menu->repeatHeld += TIME.delta;
if(menu->repeatHeld >= MENU_HELD_TIME_INITIAL) {
menu->repeatHeld = (MENU_HELD_TIME_INITIAL - MENU_HELD_TIME_REPEAT);
menuPositionMove(menu, MENU_DIRECTION_UP);
}
} else if(inputIsDown(INPUT_BIND_LEFT)) {
menu->repeatHeld += TIME.delta;
if(menu->repeatHeld >= MENU_HELD_TIME_INITIAL) {
menu->repeatHeld = (MENU_HELD_TIME_INITIAL - MENU_HELD_TIME_REPEAT);
menuPositionMove(menu, MENU_DIRECTION_LEFT);
}
} else if(inputIsDown(INPUT_BIND_RIGHT)) {
menu->repeatHeld += TIME.delta;
if(menu->repeatHeld >= MENU_HELD_TIME_INITIAL) {
menu->repeatHeld = (MENU_HELD_TIME_INITIAL - MENU_HELD_TIME_REPEAT);
menuPositionMove(menu, MENU_DIRECTION_RIGHT);
}
} else {
menu->repeatHeld = 0.0f;
}
}
void menuPositionMove(menu_t *menu, const menudirection_t direction) {
uint16_t newY, newX;
newX = menu->x;
newY = menu->y;
switch(direction) {
case MENU_DIRECTION_UP:
if(newY == 0) {
newY = menu->rows - 1;
} else {
newY--;
}
break;
case MENU_DIRECTION_DOWN:
if(newY == menu->rows - 1) {
newY = 0;
} else {
newY++;
}
break;
case MENU_DIRECTION_LEFT:
if(newX == 0) {
newX = menu->columns - 1;
} else {
newX--;
}
break;
case MENU_DIRECTION_RIGHT:
if(newX == menu->columns - 1) {
newX = 0;
} else {
newX++;
}
break;
}
menuPositionSet(menu, newX, newY);
}
void menuPositionSet(menu_t *menu, const uint16_t x, const uint16_t y) {
assertNotNull(menu, "Menu cannot be NULL.");
menu->x = x % menu->columns;
menu->y = y % menu->rows;
}

58
src/dawn/ui/menu.h Normal file
View File

@ -0,0 +1,58 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.h"
#define MENU_HELD_TIME_INITIAL 0.5f
#define MENU_HELD_TIME_REPEAT 0.2f
typedef enum {
MENU_DIRECTION_UP = 0,
MENU_DIRECTION_DOWN = 1,
MENU_DIRECTION_LEFT = 2,
MENU_DIRECTION_RIGHT = 3
} menudirection_t;
typedef struct {
uint16_t x, y;
uint16_t rows, columns;
float_t repeatHeld;
} menu_t;
/**
* Initializes the menu.
*
* @param menu Menu to initialize.
* @param rows Number of rows in the menu.
* @param columns Number of columns in the menu.
*/
void menuInit(menu_t *menu, const uint16_t rows, const uint16_t columns);
/**
* Updates the menu. Only needs to be called if the menu is active.
*
* @param menu Menu to update.
*/
void menuUpdate(menu_t *menu);
/**
* Updates the menu's cursor position.
*
* @param menu Menu to update.
* @param direction Direction to update the menu.
*/
void menuPositionMove(menu_t *menu, const menudirection_t direction);
/**
* Sets the position of the cursor in the menu.
*
* @param menu Menu to set the cursor position.
* @param x X position.
* @param y Y position.
*/
void menuPositionSet(menu_t *menu, const uint16_t x, const uint16_t y);

18
src/dawn/ui/testmenu.c Normal file
View File

@ -0,0 +1,18 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "testmenu.h"
testmenu_t TEST_MENU;
void testMenuInit() {
menuInit(&TEST_MENU.menu, 3, 4);
}
void testMenuUpdate() {
menuUpdate(&TEST_MENU.menu);
}

25
src/dawn/ui/testmenu.h Normal file
View File

@ -0,0 +1,25 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "menu.h"
typedef struct {
menu_t menu;
} testmenu_t;
extern testmenu_t TEST_MENU;
/**
* Initializes the test menu.
*/
void testMenuInit();
/**
* Updates the test menu.
*/
void testMenuUpdate();