#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h> // Include SDL_ttf header
#include <SDL2/SDL_image.h> // Include SDL_image header for PNG support
#include <switch.h>
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
// Function to render text
void renderText(SDL_Renderer *renderer, TTF_Font *font, const char *text, int x, int y, SDL_Color color) {
SDL_Surface *surface = TTF_RenderText_Solid(font, text, color);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect rect = {x, y, surface->w, surface->h};
SDL_RenderCopy(renderer, texture, NULL, &rect);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
}
int main(int argc, char *argv[]) {
// Initialize SDL, SDL_ttf, SDL_image, and libnx
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("SDL_Init failed: %s\n", SDL_GetError());
return 1;
}
if (TTF_Init() == -1) {
printf("TTF_Init failed: %s\n", TTF_GetError());
return 1;
}
if (IMG_Init(IMG_INIT_PNG) == 0) {
printf("IMG_Init failed: %s\n", IMG_GetError());
return 1;
}
romfsInit();
// Initialize the pad
PadState pad;
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
padInitializeDefault(&pad);
// Create a window and renderer
SDL_Window *window = SDL_CreateWindow("List Menu Example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
if (!window) {
printf("SDL_CreateWindow failed: %s\n", SDL_GetError());
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
printf("SDL_CreateRenderer failed: %s\n", SDL_GetError());
return 1;
}
// Load font
TTF_Font *font = TTF_OpenFont("romfs:/font.ttf", 48);
if (!font) {
printf("Failed to load font: %s\n", TTF_GetError());
return -1;
}
// Load PNG background
SDL_Texture *backgroundTexture = IMG_LoadTexture(renderer, "romfs:/background.png");
if (!backgroundTexture) {
printf("Failed to load background image: %s\n", IMG_GetError());
return -1;
}
// Define menu items
const char *menuItems[] = {"Option A", "Option B", "Option X", "Option Y", "Option +", "Option -"};
int selectedItem = 0; // Index of the currently selected item
// Colors
SDL_Color textColor = {255, 255, 255, 255}; // White text
SDL_Color itemBackgroundColor = {0, 0, 255, 255}; // Blue menu item background
SDL_Color borderColor = {0, 255, 0, 255}; // Green border for selected item
SDL_Color outerBackgroundColor = {128, 0, 128, 255}; // Purple background for the entire menu
// Calculate menu item positions
int menuItemWidth = 200; // Width of each menu item
int menuItemHeight = 60; // Height of each menu item
int menuItemSpacing = 20; // Spacing between menu items
int totalMenuHeight = (6 * menuItemHeight) + (5 * menuItemSpacing); // Total height of all menu items and spacing
int startY = (SCREEN_HEIGHT - totalMenuHeight) / 2; // Starting Y position to center the menu
int startX = (SCREEN_WIDTH - menuItemWidth) / 2; // Starting X position to center the menu
// Calculate the bounding box for the entire menu
SDL_Rect menuBoundingBox = {
startX - 10, // X position (with padding)
startY - 10, // Y position (with padding)
menuItemWidth + 20, // Width (with padding)
totalMenuHeight + 20 // Height (with padding)
};
// Main loop
bool running = true;
while (running) {
// Clear screen
SDL_RenderClear(renderer);
// Draw the PNG background
SDL_RenderCopy(renderer, backgroundTexture, NULL, NULL);
// Draw the purple background for the entire menu
SDL_SetRenderDrawColor(renderer, outerBackgroundColor.r, outerBackgroundColor.g, outerBackgroundColor.b, outerBackgroundColor.a);
SDL_RenderFillRect(renderer, &menuBoundingBox);
// Render menu items
for (int i = 0; i < 6; i++) {
int x = startX; // Center horizontally
int y = startY + i * (menuItemHeight + menuItemSpacing); // Position vertically
// Draw a blue background for the menu item
SDL_Rect itemRect = {x, y, menuItemWidth, menuItemHeight};
SDL_SetRenderDrawColor(renderer, itemBackgroundColor.r, itemBackgroundColor.g, itemBackgroundColor.b, itemBackgroundColor.a);
SDL_RenderFillRect(renderer, &itemRect);
// Draw a green border around the selected item
if (i == selectedItem) {
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, borderColor.a);
SDL_RenderDrawRect(renderer, &itemRect);
// Draw a second rectangle for the 2-pixel border
SDL_Rect innerRect = {itemRect.x + 1, itemRect.y + 1, itemRect.w - 2, itemRect.h - 2};
SDL_RenderDrawRect(renderer, &innerRect);
}
// Render menu item text
renderText(renderer, font, menuItems[i], x + 10, y + 10, textColor); // Adjust text position within the rectangle
}
// Handle input
padUpdate(&pad);
u64 kDown = padGetButtonsDown(&pad);
if (kDown & HidNpadButton_Up) {
selectedItem = (selectedItem - 1 + 6) % 6; // Move selection up
} else if (kDown & HidNpadButton_Down) {
selectedItem = (selectedItem + 1) % 6; // Move selection down
} else if (kDown & HidNpadButton_A) {
printf("%s selected!\n", menuItems[selectedItem]); // A button selects the item
} else if (kDown & HidNpadButton_B) {
printf("%s selected!\n", menuItems[selectedItem]); // B button selects the item
} else if (kDown & HidNpadButton_X) {
printf("%s selected!\n", menuItems[selectedItem]); // X button selects the item
} else if (kDown & HidNpadButton_Y) {
printf("%s selected!\n", menuItems[selectedItem]); // Y button selects the item
} else if (kDown & HidNpadButton_Plus) {
printf("%s selected!\n", menuItems[4]); // Plus button selects "Option +"
} else if (kDown & HidNpadButton_Minus) {
printf("%s selected!\n", menuItems[5]); // Minus button selects "Option -"
} else if (kDown & HidNpadButton_Plus) {
running = false; // Exit on Plus button
}
// Present the renderer
SDL_RenderPresent(renderer);
}
// Clean up
SDL_DestroyTexture(backgroundTexture);
TTF_CloseFont(font);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit(); // Quit SDL_image
TTF_Quit(); // Quit SDL_ttf
SDL_Quit();
romfsExit();
return 0;
}
[code]