213 lines
5.6 KiB
C
213 lines
5.6 KiB
C
//
|
|
// Created by bruno on 11.6.2025.
|
|
//
|
|
|
|
#include "button.h"
|
|
#include "gamestate.h"
|
|
|
|
void onStart() {
|
|
genInitMap();
|
|
screenType = SCREEN_GAME;
|
|
}
|
|
|
|
void onContinue() {
|
|
if (loadGameState(autosaveName, &mainPlayer)) {
|
|
genInitMap();
|
|
}
|
|
screenType = SCREEN_GAME;
|
|
}
|
|
|
|
void onCredits() {
|
|
screenType = SCREEN_CREDITS;
|
|
}
|
|
|
|
void onNext() {
|
|
if (!waveInfo.waveRunning && waveInfo.waveTimer > 60 * 5) {
|
|
waveInfo.waveTimer = 60 * 5;
|
|
}
|
|
}
|
|
|
|
|
|
void onQuit() {
|
|
running = false;
|
|
}
|
|
|
|
void onBack() {
|
|
screenType = SCREEN_MENU;
|
|
}
|
|
|
|
void onAtlas() {
|
|
screenType = SCREEN_ATLAS;
|
|
}
|
|
|
|
void onFont() {
|
|
screenType = SCREEN_FONTS;
|
|
}
|
|
|
|
Button buttons[5][BUTTON_COUNT];
|
|
|
|
void initButtons(void) {
|
|
buttons[0][0] = (Button){
|
|
.label = "New",
|
|
.rect = {110, DISPLAY_HEIGHT / 2, 125, 40},
|
|
.color = {100, 100, 0, 255},
|
|
.callback = onStart,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[0][1] = (Button){
|
|
.label = "Continue",
|
|
.rect = {100, DISPLAY_HEIGHT / 2 + 45, 150, 40},
|
|
.color = {0, 100, 0, 255},
|
|
.callback = onContinue,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[0][2] = (Button){
|
|
.label = "Credits",
|
|
.rect = {DISPLAY_WIDTH - 200, DISPLAY_HEIGHT - 120, 150, 40},
|
|
.color = {0, 50, 50, 255},
|
|
.callback = onCredits,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[0][3] = (Button){
|
|
.label = "Exit",
|
|
.rect = {DISPLAY_WIDTH - 200, DISPLAY_HEIGHT - 40, 100, 40},
|
|
.color = {100, 0, 0, 255},
|
|
.callback = onQuit,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[1][0] = (Button){
|
|
.label = "Back",
|
|
.rect = {DISPLAY_WIDTH / 2 - (100 / 2), DISPLAY_HEIGHT - 40, 100, 40},
|
|
.color = {100, 0, 0, 255},
|
|
.callback = onBack,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[1][1] = (Button){
|
|
.label = "Font atlas",
|
|
.rect = {DISPLAY_WIDTH - 900, DISPLAY_HEIGHT - 40, 200, 40},
|
|
.color = {100, 0, 0, 255},
|
|
.callback = onFont,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[1][2] = (Button){
|
|
.label = "Texture atlas",
|
|
.rect = {DISPLAY_WIDTH - 300, DISPLAY_HEIGHT - 40, 250, 40},
|
|
.color = {100, 0, 0, 255},
|
|
.callback = onAtlas,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[2][0] = (Button){
|
|
.label = "Next",
|
|
.rect = {395, 0, 55, 80},
|
|
.color = {64, 64, 64, 64},
|
|
.callback = onNext,
|
|
.font = &fonts[2]
|
|
};
|
|
|
|
buttons[3][0] = (Button){
|
|
.label = "Back",
|
|
.rect = {DISPLAY_WIDTH / 2 - (400 / 2), DISPLAY_HEIGHT - 40, 100, 40},
|
|
.color = {100, 0, 0, 255},
|
|
.callback = onCredits,
|
|
.font = &fonts[1]
|
|
};
|
|
|
|
buttons[4][0] = (Button){
|
|
.label = "Back",
|
|
.rect = {DISPLAY_WIDTH / 2 - (400 / 2), DISPLAY_HEIGHT - 40, 100, 40},
|
|
.color = {100, 0, 0, 255},
|
|
.callback = onCredits,
|
|
.font = &fonts[1]
|
|
};
|
|
}
|
|
|
|
|
|
void renderButtons(SDL_Renderer *renderer, Player player) {
|
|
for (int i = 0; i < BUTTON_COUNT; i++) {
|
|
renderButton(renderer, buttons[screenType][i], player);
|
|
}
|
|
}
|
|
|
|
|
|
void renderButton(SDL_Renderer *renderer, Button btn, Player player) {
|
|
if (btn.font == NULL || btn.label == NULL || strlen(btn.label) == 0) {
|
|
return;
|
|
}
|
|
|
|
// Check for hover/click
|
|
bool hovered = (player.cursor.windowX >= btn.rect.x && player.cursor.windowX <= btn.rect.x + btn.rect.w &&
|
|
player.cursor.windowY >= btn.rect.y && player.cursor.windowY <= btn.rect.y + btn.rect.h);
|
|
|
|
// Set color and draw background
|
|
SDL_Color bgColor = btn.color;
|
|
if (hovered) {
|
|
bgColor.a = btn.color.a / 2;
|
|
}
|
|
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, bgColor.a);
|
|
SDL_RenderFillRect(renderer, &btn.rect);
|
|
|
|
// Split label into lines
|
|
const char *label = btn.label;
|
|
const int maxLines = 10; // Hard cap for sanity
|
|
const char *lines[maxLines];
|
|
int lineCount = 0;
|
|
|
|
lines[lineCount++] = label;
|
|
for (const char *p = label; *p && lineCount < maxLines; p++) {
|
|
if (*p == '\n') {
|
|
lines[lineCount++] = p + 1;
|
|
}
|
|
}
|
|
|
|
// Get length of each line and find max width (for centering)
|
|
int maxLineWidth = 0;
|
|
int lineWidths[maxLines];
|
|
int fontSize = btn.font->size;
|
|
|
|
for (int i = 0; i < lineCount; i++) {
|
|
const char *lineStart = lines[i];
|
|
const char *lineEnd = strchr(lineStart, '\n');
|
|
int lineLen = lineEnd ? (lineEnd - lineStart) : strlen(lineStart);
|
|
|
|
int lineWidth = lineLen * fontSize;
|
|
lineWidths[i] = lineWidth;
|
|
if (lineWidth > maxLineWidth) {
|
|
maxLineWidth = lineWidth;
|
|
}
|
|
}
|
|
|
|
// Calculate starting Y to vertically center all lines
|
|
int totalHeight = lineCount * fontSize;
|
|
int startY = btn.rect.y + (btn.rect.h - totalHeight) / 2;
|
|
|
|
// Render each line centered horizontally
|
|
for (int i = 0; i < lineCount; i++) {
|
|
const char *lineStart = lines[i];
|
|
const char *lineEnd = strchr(lineStart, '\n');
|
|
int lineLen = lineEnd ? (lineEnd - lineStart) : strlen(lineStart);
|
|
|
|
char buffer[256];
|
|
strncpy(buffer, lineStart, lineLen);
|
|
buffer[lineLen] = '\0';
|
|
|
|
int x = btn.rect.x + (btn.rect.w - lineWidths[i]) / 2;
|
|
int y = startY + i * fontSize;
|
|
|
|
renderText(renderer, *btn.font, buffer, x, y);
|
|
}
|
|
|
|
// Trigger callback if clicked
|
|
if (hovered && (player.mouseButtons & SDL_BUTTON_LMASK)) {
|
|
if (btn.callback) {
|
|
btn.callback();
|
|
}
|
|
}
|
|
}
|