#include "state_menu_main.hpp" #include "defaults/ui.hpp" #include "game/game.hpp" #include #include #include #include StateMenuMain::StateMenuMain() {} StateMenuMain::~StateMenuMain() {} static SDL_FRect menu_rect{}; bool StateMenuMain::Init(Game* game) { audio = game->audio; game->running = game->running; // Set up buttons buttons.push_back({ MenuState::CONTI, "Continue", {300, 200, 200, 50}, false}); buttons.push_back({ MenuState::SAVE, "Save Game", {300, 260, 200, 50}, false}); buttons.push_back({ MenuState::LOAD, "Load Game", {300, 260, 200, 50}, false}); buttons.push_back({ MenuState::NEW, "New Game", {300, 200, 200, 50}, false}); buttons.push_back({ MenuState::QUIT, "Quit", {300, 320, 200, 50}, false}); buttons.push_back({ MenuState::NEW_CHEAT, "New Cheat", {300, 200, 200, 50}, false}); cursor = game->cursor; cursor->set_State(CursorState::ANIMATED); return true; } void runState(MenuState state, Game* game) { switch(state) { case MenuState::CONTI: game->set_State(GameState_e::STATE_PLAYING, NewGameState_e::NONE); break; case MenuState::SAVE: game->Save(game->active_game_dir); break; case MenuState::LOAD: game->set_State(GameState_e::STATE_PLAYING, NewGameState_e::LOAD); break; case MenuState::NEW: game->is_cheating = false; game->set_State(GameState_e::STATE_PLAYING, NewGameState_e::NEW); break; case MenuState::QUIT: game->running = false; break; case MenuState::NEW_CHEAT: game->is_cheating = true; game->set_State(GameState_e::STATE_PLAYING, NewGameState_e::NEW); break; } } void StateMenuMain::handle_Events(SDL_Event& event, Game* game) { if(event.type == SDL_EVENT_MOUSE_MOTION) { float mx = event.motion.x; float my = event.motion.y; for(auto& btn : buttons) { SDL_FPoint p = {mx, my}; btn.hovered = SDL_PointInRectFloat(&p, &btn.rect); } } else if(event.type == SDL_EVENT_MOUSE_BUTTON_UP && event.button.button == SDL_BUTTON_LEFT) { for(size_t i=0; i(game->win_size.w) / 2 - button_width / 2; size_t start_y = static_cast(game->win_size.h) / 2 - total_height / 2 + padding; static int last_clicked = -1; bool any_button_hovered = false; for(size_t i = 0; i < buttons.size(); ++i) { if(buttons[i].hovered) { any_button_hovered = true; if ( (int)i != last_clicked ) { if (audio->is_Playing("menu.hover") ) audio->Stop("menu.hover"); audio->Play("menu.hover"); last_clicked = i; } } buttons[i].rect.x = start_x; buttons[i].rect.y = start_y + i * (button_height + button_gap); buttons[i].rect.w = button_width; buttons[i].rect.h = button_height; } if (!any_button_hovered) { last_clicked = -1; if (audio->is_Playing("menu.hover") ) audio->Stop("menu.hover"); } // Store menu_rect for rendering menu_rect.x = start_x - 30; menu_rect.y = start_y - padding; menu_rect.w = button_width + 60; menu_rect.h = total_height; } void StateMenuMain::Render(Game* game) { SDL_Renderer* r = game->renderer; // Fullscreen dim background SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(r, 20, 20, 35, 180); SDL_FRect dim = {0, 0, (float)game->win_size.w, (float)game->win_size.h}; SDL_RenderFillRect(r, &dim); // Menu background SDL_SetRenderDrawColor(r, 40, 40, 70, 230); SDL_RenderFillRect(r, &menu_rect); // Menu border SDL_SetRenderDrawColor(r, 120, 120, 170, 255); SDL_RenderRect(r, &menu_rect); for(int i = 1; i < 6; ++i) { SDL_FRect inner = { menu_rect.x + i, menu_rect.y + i, menu_rect.w - 2*i, menu_rect.h - 2*i }; SDL_RenderRect(r, &inner); } // Render buttons for(size_t i = 0; i < buttons.size(); ++i) { auto& btn = buttons[i]; // Border float bd_w = 3; SDL_FRect bd = {btn.rect.x-bd_w, btn.rect.y-bd_w, btn.rect.w+bd_w*2, btn.rect.h+bd_w*2 }; SDL_SetRenderDrawColor(r, 70, 70, 120, 255); SDL_RenderFillRect(r, &bd); // Button background if(btn.hovered) SDL_SetRenderDrawColor(r, 90, 170, 220, 255); else if(i == static_cast(selected_index)) SDL_SetRenderDrawColor(r, 80, 120, 170, 255); else SDL_SetRenderDrawColor(r, 70, 70, 120, 255); SDL_RenderFillRect(r, &btn.rect); // Button text SDL_Color color = {255, 255, 255, 255}; SDL_Surface* surf = TTF_RenderText_Blended(Ui::font_menu_bold, btn.text.c_str(), btn.text.length(), color); SDL_Texture* tex = SDL_CreateTextureFromSurface(r, surf); float tw, th; SDL_GetTextureSize(tex, &tw, &th); SDL_FRect dst = { btn.rect.x + (btn.rect.w - tw) * 0.5f, btn.rect.y + (btn.rect.h - th) * 0.5f, tw, th }; SDL_RenderTexture(r, tex, nullptr, &dst); SDL_DestroyTexture(tex); SDL_DestroySurface(surf); } }