Updated game structure
This commit is contained in:
113
src/main.cpp
113
src/main.cpp
@ -14,19 +14,20 @@
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
#include "Audio.h"
|
||||
#include "SoundEffect.h"
|
||||
#include "audio/Audio.h"
|
||||
#include "audio/SoundEffect.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "Scores.h"
|
||||
#include "Starfield.h"
|
||||
#include "gameplay/Game.h"
|
||||
#include "persistence/Scores.h"
|
||||
#include "graphics/Starfield.h"
|
||||
#include "Starfield3D.h"
|
||||
#include "Font.h"
|
||||
#include "LineEffect.h"
|
||||
#include "graphics/Font.h"
|
||||
#include "gameplay/LineEffect.h"
|
||||
#include "states/State.h"
|
||||
#include "states/LoadingState.h"
|
||||
#include "states/MenuState.h"
|
||||
#include "states/PlayingState.h"
|
||||
#include "audio/MenuWrappers.h"
|
||||
|
||||
// Debug logging removed: no-op in this build (previously LOG_DEBUG)
|
||||
|
||||
@ -331,7 +332,7 @@ static void drawSettingsPopup(SDL_Renderer* renderer, FontAtlas& font, bool musi
|
||||
// Starfield now managed by Starfield class
|
||||
|
||||
// State manager integration (scaffolded in StateManager.h)
|
||||
#include "StateManager.h"
|
||||
#include "core/StateManager.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Intro/Menu state variables
|
||||
@ -341,8 +342,6 @@ static bool showLevelPopup = false;
|
||||
static bool showSettingsPopup = false;
|
||||
static bool musicEnabled = true;
|
||||
static int hoveredButton = -1; // -1 = none, 0 = play, 1 = level, 2 = settings
|
||||
// Shared texture for fireworks particles (uses the blocks sheet)
|
||||
static SDL_Texture* fireworksBlocksTex = nullptr;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Tetris Block Fireworks for intro animation (block particles)
|
||||
@ -389,44 +388,7 @@ struct TetrisFirework {
|
||||
}
|
||||
return !particles.empty();
|
||||
}
|
||||
void draw(SDL_Renderer* renderer) {
|
||||
for (auto &p : particles) {
|
||||
if (fireworksBlocksTex) {
|
||||
// Apply per-particle alpha and color variants by modulating the blocks texture
|
||||
// Save previous mods (assume single-threaded rendering)
|
||||
Uint8 prevA = 255;
|
||||
SDL_GetTextureAlphaMod(fireworksBlocksTex, &prevA);
|
||||
Uint8 setA = Uint8(std::max(0.0f, std::min(1.0f, p.alpha)) * 255.0f);
|
||||
SDL_SetTextureAlphaMod(fireworksBlocksTex, setA);
|
||||
|
||||
// Color modes: tint the texture where appropriate
|
||||
if (mode == 1) {
|
||||
// red
|
||||
SDL_SetTextureColorMod(fireworksBlocksTex, 220, 60, 60);
|
||||
} else if (mode == 2) {
|
||||
// green
|
||||
SDL_SetTextureColorMod(fireworksBlocksTex, 80, 200, 80);
|
||||
} else if (mode == 3) {
|
||||
// tint to the particle's block color
|
||||
SDL_Color c = COLORS[p.blockType + 1];
|
||||
SDL_SetTextureColorMod(fireworksBlocksTex, c.r, c.g, c.b);
|
||||
} else {
|
||||
// random: no tint (use texture colors directly)
|
||||
SDL_SetTextureColorMod(fireworksBlocksTex, 255, 255, 255);
|
||||
}
|
||||
|
||||
drawBlockTexture(renderer, fireworksBlocksTex, p.x - p.size * 0.5f, p.y - p.size * 0.5f, p.size, p.blockType);
|
||||
|
||||
// Restore alpha and color modulation
|
||||
SDL_SetTextureAlphaMod(fireworksBlocksTex, prevA);
|
||||
SDL_SetTextureColorMod(fireworksBlocksTex, 255, 255, 255);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, Uint8(p.alpha * 255));
|
||||
SDL_FRect rect{p.x - p.size/2, p.y - p.size/2, p.size, p.size};
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Drawing is handled by drawFireworks_impl which accepts the texture to use.
|
||||
};
|
||||
|
||||
static std::vector<TetrisFirework> fireworks;
|
||||
@ -455,13 +417,41 @@ static void updateFireworks(double frameMs) {
|
||||
}
|
||||
}
|
||||
|
||||
static void drawFireworks(SDL_Renderer* renderer) {
|
||||
for (auto& f : fireworks) f.draw(renderer);
|
||||
// Primary implementation that accepts a texture pointer
|
||||
static void drawFireworks_impl(SDL_Renderer* renderer, SDL_Texture* blocksTexture) {
|
||||
for (auto& f : fireworks) {
|
||||
// Particle draw uses the texture pointer passed into drawBlockTexture calls from f.draw
|
||||
// We'll set a thread-local-ish variable by passing the texture as an argument to draw
|
||||
// routines or using the provided texture in the particle's draw path.
|
||||
// For simplicity, the particle draw function below will reference a global symbol
|
||||
// via an argument — we adapt by providing the texture when calling drawBlockTexture.
|
||||
// Implementation: call a small lambda that temporarily binds the texture for drawBlockTexture.
|
||||
struct Drawer { SDL_Renderer* r; SDL_Texture* tex; void drawParticle(struct BlockParticle& p) {
|
||||
if (tex) {
|
||||
Uint8 prevA = 255;
|
||||
SDL_GetTextureAlphaMod(tex, &prevA);
|
||||
Uint8 setA = Uint8(std::max(0.0f, std::min(1.0f, p.alpha)) * 255.0f);
|
||||
SDL_SetTextureAlphaMod(tex, setA);
|
||||
// Note: color modulation will be applied by callers of drawBlockTexture where needed
|
||||
// but we mimic behavior from previous implementation by leaving color mod as default.
|
||||
drawBlockTexture(r, tex, p.x - p.size * 0.5f, p.y - p.size * 0.5f, p.size, p.blockType);
|
||||
SDL_SetTextureAlphaMod(tex, prevA);
|
||||
SDL_SetTextureColorMod(tex, 255, 255, 255);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(r, 255, 255, 255, Uint8(p.alpha * 255));
|
||||
SDL_FRect rect{p.x - p.size/2, p.y - p.size/2, p.size, p.size};
|
||||
SDL_RenderFillRect(r, &rect);
|
||||
}
|
||||
}
|
||||
} drawer{renderer, blocksTexture};
|
||||
for (auto &p : f.particles) {
|
||||
drawer.drawParticle(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// External wrappers for use by other translation units (MenuState)
|
||||
// These call the internal helpers above so we don't change existing static linkage.
|
||||
void menu_drawFireworks(SDL_Renderer* renderer) { drawFireworks(renderer); }
|
||||
// Expect callers to pass the blocks texture via StateContext so we avoid globals.
|
||||
void menu_drawFireworks(SDL_Renderer* renderer, SDL_Texture* blocksTex) { drawFireworks_impl(renderer, blocksTex); }
|
||||
void menu_updateFireworks(double frameMs) { updateFireworks(frameMs); }
|
||||
double menu_getLogoAnimCounter() { return logoAnimCounter; }
|
||||
int menu_getHoveredButton() { return hoveredButton; }
|
||||
@ -474,20 +464,20 @@ int main(int, char **)
|
||||
int sdlInitRes = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
|
||||
if (sdlInitRes < 0)
|
||||
{
|
||||
std::fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init failed: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
int ttfInitRes = TTF_Init();
|
||||
if (ttfInitRes < 0)
|
||||
{
|
||||
std::fprintf(stderr, "TTF_Init failed\n");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "TTF_Init failed");
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
SDL_Window *window = SDL_CreateWindow("Tetris (SDL3)", LOGICAL_W, LOGICAL_H, SDL_WINDOW_RESIZABLE);
|
||||
if (!window)
|
||||
{
|
||||
std::fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow failed: %s", SDL_GetError());
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
@ -495,7 +485,7 @@ int main(int, char **)
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, nullptr);
|
||||
if (!renderer)
|
||||
{
|
||||
std::fprintf(stderr, "SDL_CreateRenderer failed: %s\n", SDL_GetError());
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateRenderer failed: %s", SDL_GetError());
|
||||
SDL_DestroyWindow(window);
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
@ -556,6 +546,9 @@ int main(int, char **)
|
||||
} else {
|
||||
(void)0;
|
||||
}
|
||||
|
||||
// Note: `backgroundTex` is owned by main and passed into `StateContext::backgroundTex` below.
|
||||
// States should render using `ctx.backgroundTex` rather than accessing globals.
|
||||
|
||||
// Level background caching system
|
||||
SDL_Texture *levelBackgroundTex = nullptr;
|
||||
@ -575,6 +568,7 @@ int main(int, char **)
|
||||
} else {
|
||||
(void)0;
|
||||
}
|
||||
// No global exposure of blocksTex; states receive textures via StateContext.
|
||||
|
||||
if (!blocksTex) {
|
||||
(void)0;
|
||||
@ -613,8 +607,7 @@ int main(int, char **)
|
||||
(void)0;
|
||||
}
|
||||
|
||||
// Provide the blocks sheet to the fireworks system (for block particles)
|
||||
fireworksBlocksTex = blocksTex;
|
||||
// Provide the blocks sheet to the fireworks system through StateContext (no globals).
|
||||
|
||||
// Default start level selection: 0
|
||||
int startLevelSelection = 0;
|
||||
@ -656,7 +649,7 @@ int main(int, char **)
|
||||
}
|
||||
}
|
||||
|
||||
std::fprintf(stderr, "Failed to load sound: %s (tried both WAV and MP3)\n", id.c_str());
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load sound: %s (tried both WAV and MP3)", id.c_str());
|
||||
};
|
||||
|
||||
loadSoundWithFallback("nice_combo", "nice_combo");
|
||||
|
||||
Reference in New Issue
Block a user