diff --git a/lib/AudioFile b/lib/AudioFile new file mode 160000 index 00000000..bcb61a47 --- /dev/null +++ b/lib/AudioFile @@ -0,0 +1 @@ +Subproject commit bcb61a47e64fe4e7fc3d8a8664b8a23a192bddb7 diff --git a/src/dawn/display/draw/drawstateoverworld.c b/src/dawn/display/draw/drawstateoverworld.c index d72643c5..36ff21a9 100644 --- a/src/dawn/display/draw/drawstateoverworld.c +++ b/src/dawn/display/draw/drawstateoverworld.c @@ -16,7 +16,7 @@ void drawStateOverworld() { map_t *map = GAME.currentMap; if(map == NULL) return; - // Try get player + // Draw the map, based on player position entity_t *player = mapEntityGetByType(map, ENTITY_TYPE_PLAYER); uint16_t cameraPositionX, cameraPositionY; if(player == NULL) { @@ -27,14 +27,14 @@ void drawStateOverworld() { cameraPositionY = player->y; } - drawMap( - GAME.currentMap, - cameraPositionX, cameraPositionY, - 0, 0, - FRAME_WIDTH, FRAME_HEIGHT - ); + // drawMap( + // GAME.currentMap, + // cameraPositionX, cameraPositionY, + // 0, 0, + // FRAME_WIDTH, FRAME_HEIGHT + // ); // Draw UI - drawUITextbox(); + // drawUITextbox(); drawUITestMenu(); } \ No newline at end of file diff --git a/src/dawn/display/draw/drawui.c b/src/dawn/display/draw/drawui.c index a09279c7..919b55f5 100644 --- a/src/dawn/display/draw/drawui.c +++ b/src/dawn/display/draw/drawui.c @@ -12,6 +12,7 @@ #include "display/draw/drawtext.h" #include "ui/textbox.h" #include "ui/testmenu.h" +#include "util/math.h" void drawUIBox( const uint16_t x, @@ -60,66 +61,134 @@ void drawUIBox( } void drawUIMenu( - const menu_t *menu, + menu_t *menu, const uint16_t x, const uint16_t y, const uint16_t width, - const char_t* strings[], - const int16_t stringCount, + const uint16_t height, 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 + uint16_t colWidth; + uint16_t startingCol; + uint16_t startingRow; + uint16_t rowCount; + uint16_t colCount; + char_t *str; + size_t i; - // Draw the menu - for(uint16_t row = 0; row < menu->rows; row++) { - for(uint16_t col = 0; col < menu->columns; col++) { + // Determine the width of each column. This must include space for the cursor + // and the text. + if(menu->columns == 1 || rowCount == 0) { + colWidth = width; + colCount = 1; + } else { + size_t longestString = 0; + i = 0; + while(true) { + str = menu->strings[i++]; + if(str == NULL) break; + + size_t len = strlen(str); + if(len > longestString) longestString = len; + + // If we overrun the size of the box, we can stop looking. + if((len+1) > width) { + longestString = width; + break; + } + } + + // How many columns can we fit? + uint16_t possibleColumnsAtThisWidth = width / (longestString + 1); + + if(possibleColumnsAtThisWidth < menu->columns) { + // We need to take a subset of the columns + colWidth = width / possibleColumnsAtThisWidth; + colCount = possibleColumnsAtThisWidth; + } else { + // We can fit all columns in + colWidth = width / menu->columns; + colCount = menu->columns; + } + + assertTrue(longestString != 0, "Longest string has length 0?"); + } + + // Determine count of rows to render + if(rowCount == 1) { + rowCount = 1; + } else { + rowCount = mathMin(rowCount, height); + } + + // Where are we rendering from? + startingCol = menu->renderOffsetX; + + if(menu->x >= startingCol + colCount) { + startingCol = (menu->x + 1) - colCount; + } else if(menu->x < startingCol) { + startingCol = menu->x; + } + + startingRow = menu->renderOffsetY; + if(menu->y >= startingRow + rowCount) { + startingRow = (menu->y + 1) - rowCount; + } else if(menu->y < startingRow) { + startingRow = menu->y; + } + + // Update back to the menu + menu->renderOffsetX = startingCol; + menu->renderOffsetY = startingRow; + + for(uint16_t col = startingCol; col < startingCol+colCount; col++) { + for(uint16_t row = startingRow; row < startingRow+rowCount; row++) { uint16_t index = (row * menu->columns) + col; - if(index >= stringCount) break; + if(menu->strings[index] == NULL) continue; drawText( - strings[index], - -1, - x + (col * stringWidth) + 1, - y + row, + menu->strings[index], + colWidth, + x + (colWidth * (col - startingCol)) + 1, + y + (row - startingRow), textColor ); } } // Draw the cursor - size_t i = (x + (menu->x * stringWidth)) + ((y + menu->y) * FRAME_WIDTH); + i = ( + x + ((menu->x - startingCol) * colWidth) + ) + ( + (y + (menu->y - startingRow)) * FRAME_WIDTH + ); FRAME_BUFFER[i] = '>'; FRAME_COLOR[i] = cursorColor; } void drawUIMenuBox( - const menu_t *menu, + 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 - // ); + drawUIMenu( + menu, + x + 1, y + 1, + width - 2, height - 2, + cursorColor, textColor + ); } void drawUITextbox() { @@ -159,44 +228,10 @@ void drawUITextbox() { } 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 + COLOR_CYAN, COLOR_RED, COLOR_WHITE ); } \ No newline at end of file diff --git a/src/dawn/display/draw/drawui.h b/src/dawn/display/draw/drawui.h index 27157e0c..23fcde02 100644 --- a/src/dawn/display/draw/drawui.h +++ b/src/dawn/display/draw/drawui.h @@ -40,19 +40,16 @@ void drawUIBox( * @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 height The height of the menu. * @param cursorColor The color of the cursor. * @param textColor The color of the text. */ void drawUIMenu( - const menu_t *menu, + menu_t *menu, const uint16_t x, const uint16_t y, const uint16_t width, - - const char_t* strings[], - const int16_t stringCount, + const uint16_t height, const uint8_t cursorColor, const uint8_t textColor ); @@ -65,20 +62,16 @@ void drawUIMenu( * @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, + 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 diff --git a/src/dawn/ui/menu.c b/src/dawn/ui/menu.c index d4b0b40c..e22e2e7d 100644 --- a/src/dawn/ui/menu.c +++ b/src/dawn/ui/menu.c @@ -10,7 +10,11 @@ #include "input.h" #include "game/time.h" -void menuInit(menu_t *menu, const uint16_t rows, const uint16_t columns) { +void menuInit( + menu_t *menu, + const uint16_t columns, + const uint16_t rows +) { assertNotNull(menu, "Menu cannot be NULL."); assertTrue(rows > 0, "Rows must be greater than 0."); assertTrue(columns > 0, "Columns must be greater than 0."); @@ -109,4 +113,15 @@ 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; + + // Is there a string here? + uint16_t index = (menu->y * menu->columns) + menu->x; + if(menu->strings[index] == NULL) { + if(menu->y == 0) { + // idk yet + menu->x = 0; + } else { + menu->y--; + } + } } \ No newline at end of file diff --git a/src/dawn/ui/menu.h b/src/dawn/ui/menu.h index 6717e988..dc4be137 100644 --- a/src/dawn/ui/menu.h +++ b/src/dawn/ui/menu.h @@ -10,6 +10,7 @@ #define MENU_HELD_TIME_INITIAL 0.5f #define MENU_HELD_TIME_REPEAT 0.2f +#define MENU_ITEM_COUNT_MAX 256 typedef enum { MENU_DIRECTION_UP = 0, @@ -22,6 +23,10 @@ typedef struct { uint16_t x, y; uint16_t rows, columns; float_t repeatHeld; + const char_t* strings[MENU_ITEM_COUNT_MAX]; + + // Visual things + uint16_t renderOffsetX, renderOffsetY; } menu_t; /** diff --git a/src/dawn/ui/testmenu.c b/src/dawn/ui/testmenu.c index d7b35539..52ca6d7e 100644 --- a/src/dawn/ui/testmenu.c +++ b/src/dawn/ui/testmenu.c @@ -10,7 +10,30 @@ testmenu_t TEST_MENU; void testMenuInit() { - menuInit(&TEST_MENU.menu, 3, 4); + 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", + }; + + uint16_t columns = 3; + uint16_t rows = 6; + menuInit(&TEST_MENU.menu, columns, rows); + memcpy(TEST_MENU.menu.strings, strings, sizeof(strings)); } void testMenuUpdate() {