Hopefully last commit
This commit is contained in:
212
util/button.c
Normal file
212
util/button.c
Normal file
@@ -0,0 +1,212 @@
|
||||
//
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user