some problems fixed
This commit is contained in:
@ -187,15 +187,10 @@ void LevelSelectorState::handleEvent(const SDL_Event& e) {
|
||||
if (ctx.startLevelSelection) *ctx.startLevelSelection = hoveredLevel;
|
||||
} else if (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
|
||||
if (e.button.button == SDL_BUTTON_LEFT) {
|
||||
// compute visible logical viewport
|
||||
float vw = (lastLogicalScale > 0.f) ? float(lastLogicalVP.w) / lastLogicalScale : float(LOGICAL_W);
|
||||
float vh = (lastLogicalScale > 0.f) ? float(lastLogicalVP.h) / lastLogicalScale : float(LOGICAL_H);
|
||||
float offX = 0.f;
|
||||
if (lastLogicalScale > 0.f) offX = (vw / 2.f) - (float(LOGICAL_W) / 2.f);
|
||||
// convert mouse to logical coords
|
||||
// convert mouse to logical coords (viewport is already centered)
|
||||
float lx = (float(e.button.x) - float(lastLogicalVP.x)) / (lastLogicalScale > 0.f ? lastLogicalScale : 1.f);
|
||||
float ly = (float(e.button.y) - float(lastLogicalVP.y)) / (lastLogicalScale > 0.f ? lastLogicalScale : 1.f);
|
||||
SDL_FRect panel = DrawPanel(nullptr, vw, vh, /*draw=*/false, offX, 0.f);
|
||||
SDL_FRect panel = DrawPanel(nullptr, LOGICAL_W, LOGICAL_H, /*draw=*/false, 0.f, 0.f);
|
||||
Grid g = MakeGrid(panel);
|
||||
int hit = HitTest(g, int(lx), int(ly));
|
||||
if (hit != -1) {
|
||||
@ -205,14 +200,10 @@ void LevelSelectorState::handleEvent(const SDL_Event& e) {
|
||||
}
|
||||
}
|
||||
} else if (e.type == SDL_EVENT_MOUSE_MOTION) {
|
||||
// compute visible logical viewport and convert mouse coords once
|
||||
float vw = (lastLogicalScale > 0.f) ? float(lastLogicalVP.w) / lastLogicalScale : float(LOGICAL_W);
|
||||
float vh = (lastLogicalScale > 0.f) ? float(lastLogicalVP.h) / lastLogicalScale : float(LOGICAL_H);
|
||||
float offX = 0.f;
|
||||
if (lastLogicalScale > 0.f) offX = (vw / 2.f) - (float(LOGICAL_W) / 2.f);
|
||||
// convert mouse to logical coords (viewport is already centered)
|
||||
float lx = (float(e.motion.x) - float(lastLogicalVP.x)) / (lastLogicalScale > 0.f ? lastLogicalScale : 1.f);
|
||||
float ly = (float(e.motion.y) - float(lastLogicalVP.y)) / (lastLogicalScale > 0.f ? lastLogicalScale : 1.f);
|
||||
SDL_FRect panel = DrawPanel(nullptr, vw, vh, /*draw=*/false, offX, 0.f);
|
||||
SDL_FRect panel = DrawPanel(nullptr, LOGICAL_W, LOGICAL_H, /*draw=*/false, 0.f, 0.f);
|
||||
Grid g = MakeGrid(panel);
|
||||
hoveredLevel = HitTest(g, int(lx), int(ly));
|
||||
}
|
||||
@ -233,18 +224,11 @@ void LevelSelectorState::render(SDL_Renderer* renderer, float logicalScale, SDL_
|
||||
void LevelSelectorState::drawLevelSelectionPopup(SDL_Renderer* renderer) {
|
||||
if (!renderer) return;
|
||||
|
||||
// Important: main sets viewport + logical scale before calling us.
|
||||
// Draw in logical coordinates to avoid artifacts in fullscreen.
|
||||
// Use the actual visible logical size (viewport in logical coords) instead of hardcoded constants
|
||||
float vw = (lastLogicalScale > 0.f) ? float(lastLogicalVP.w) / lastLogicalScale : float(LOGICAL_W);
|
||||
float vh = (lastLogicalScale > 0.f) ? float(lastLogicalVP.h) / lastLogicalScale : float(LOGICAL_H);
|
||||
|
||||
// compute horizontal offset so content centers within the visible logical viewport
|
||||
float offX = 0.f;
|
||||
if (lastLogicalScale > 0.f) {
|
||||
float visibleLogicalW = float(lastLogicalVP.w) / lastLogicalScale;
|
||||
offX = (visibleLogicalW / 2.f) - (vw / 2.f);
|
||||
}
|
||||
// Since ApplicationManager sets up a centered viewport, we draw directly in logical coordinates
|
||||
// The viewport (LOGICAL_W x LOGICAL_H) is already centered within the window
|
||||
float vw = float(LOGICAL_W);
|
||||
float vh = float(LOGICAL_H);
|
||||
float offX = 0.f; // No offset needed since viewport is centered
|
||||
|
||||
// Panel and title strip (in logical space)
|
||||
SDL_FRect panel = DrawPanel(renderer, vw, vh-140.0f, /*draw=*/true, offX, 0.f);
|
||||
@ -268,19 +252,14 @@ void LevelSelectorState::drawLevelSelectionPopup(SDL_Renderer* renderer) {
|
||||
}
|
||||
|
||||
bool LevelSelectorState::isMouseInPopup(float mouseX, float mouseY, float& popupX, float& popupY, float& popupW, float& popupH) {
|
||||
// Re-implement using new panel geometry in window coordinates
|
||||
// Convert from window pixels to logical coords using cached viewport/scale
|
||||
// Simplified: viewport is already centered, just convert mouse to logical coords
|
||||
(void)mouseX; (void)mouseY;
|
||||
float lx = 0.f, ly = 0.f;
|
||||
if (lastLogicalScale > 0.0f) {
|
||||
lx = (float(mouseX) - float(lastLogicalVP.x)) / lastLogicalScale;
|
||||
ly = (float(mouseY) - float(lastLogicalVP.y)) / lastLogicalScale;
|
||||
}
|
||||
float vw = (lastLogicalScale > 0.f) ? float(lastLogicalVP.w) / lastLogicalScale : float(LOGICAL_W);
|
||||
float vh = (lastLogicalScale > 0.f) ? float(lastLogicalVP.h) / lastLogicalScale : float(LOGICAL_H);
|
||||
float offX = 0.f;
|
||||
if (lastLogicalScale > 0.f) offX = (vw / 2.f) - (float(LOGICAL_W) / 2.f);
|
||||
SDL_FRect p = DrawPanel(nullptr, vw, vh, /*draw=*/false, offX, 0.f);
|
||||
SDL_FRect p = DrawPanel(nullptr, LOGICAL_W, LOGICAL_H, /*draw=*/false, 0.f, 0.f);
|
||||
popupX = p.x; popupY = p.y; popupW = p.w; popupH = p.h;
|
||||
return lx >= popupX && lx <= popupX + popupW && ly >= popupY && ly <= popupY + popupH;
|
||||
}
|
||||
@ -292,11 +271,7 @@ int LevelSelectorState::getLevelFromMouse(float mouseX, float mouseY, float popu
|
||||
lx = (float(mouseX) - float(lastLogicalVP.x)) / lastLogicalScale;
|
||||
ly = (float(mouseY) - float(lastLogicalVP.y)) / lastLogicalScale;
|
||||
}
|
||||
float vw = (lastLogicalScale > 0.f) ? float(lastLogicalVP.w) / lastLogicalScale : float(LOGICAL_W);
|
||||
float vh = (lastLogicalScale > 0.f) ? float(lastLogicalVP.h) / lastLogicalScale : float(LOGICAL_H);
|
||||
float offX = 0.f;
|
||||
if (lastLogicalScale > 0.f) offX = (vw / 2.f) - (float(LOGICAL_W) / 2.f);
|
||||
SDL_FRect p = DrawPanel(nullptr, vw, vh, /*draw=*/false, offX, 0.f);
|
||||
SDL_FRect p = DrawPanel(nullptr, LOGICAL_W, LOGICAL_H, /*draw=*/false, 0.f, 0.f);
|
||||
Grid g = MakeGrid(p);
|
||||
return HitTest(g, (int)lx, (int)ly);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "persistence/Scores.h"
|
||||
#include "graphics/Font.h"
|
||||
#include "../core/GlobalState.h"
|
||||
#include "../audio/Audio.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
@ -42,14 +43,10 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
{
|
||||
FILE* f = fopen("tetris_trace.log", "a"); if (f) { fprintf(f, "MenuState::render entry\n"); fclose(f); }
|
||||
}
|
||||
// Compute content offset using the same math as main
|
||||
float winW = float(logicalVP.w);
|
||||
float winH = float(logicalVP.h);
|
||||
float contentScale = logicalScale;
|
||||
float contentW = LOGICAL_W * contentScale;
|
||||
float contentH = LOGICAL_H * contentScale;
|
||||
float contentOffsetX = (winW - contentW) * 0.5f / contentScale;
|
||||
float contentOffsetY = (winH - contentH) * 0.5f / contentScale;
|
||||
// Since ApplicationManager sets up a centered viewport, we draw directly in logical coordinates
|
||||
// No additional content offset is needed - the viewport itself handles centering
|
||||
float contentOffsetX = 0.0f;
|
||||
float contentOffsetY = 0.0f;
|
||||
|
||||
// Background is drawn by main (stretched to the full window) to avoid double-draw.
|
||||
|
||||
@ -119,16 +116,17 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
useFont->draw(renderer, colX[4], scoresStartY - 28, "LEVEL", 1.1f, SDL_Color{200,200,220,255});
|
||||
useFont->draw(renderer, colX[5], scoresStartY - 28, "TIME", 1.1f, SDL_Color{200,200,220,255});
|
||||
}
|
||||
|
||||
// Center columns around mid X, wider
|
||||
float cx = LOGICAL_W * 0.5f + contentOffsetX;
|
||||
float colX[] = { cx - 280, cx - 180, cx - 20, cx + 90, cx + 200, cx + 300 };
|
||||
|
||||
for (size_t i = 0; i < maxDisplay; ++i)
|
||||
{
|
||||
float baseY = scoresStartY + i * 25;
|
||||
float wave = std::sin((float)GlobalState::instance().logoAnimCounter * 0.006f + i * 0.25f) * 6.0f; // subtle wave
|
||||
float y = baseY + wave;
|
||||
|
||||
// Center columns around mid X, wider
|
||||
float cx = LOGICAL_W * 0.5f + contentOffsetX;
|
||||
float colX[] = { cx - 280, cx - 180, cx - 20, cx + 90, cx + 200, cx + 300 };
|
||||
|
||||
char rankStr[8];
|
||||
std::snprintf(rankStr, sizeof(rankStr), "%zu.", i + 1);
|
||||
if (useFont) useFont->draw(renderer, colX[0], y, rankStr, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
@ -150,6 +148,8 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
}
|
||||
|
||||
// Draw bottom action buttons with responsive sizing (reduced to match main mouse hit-test)
|
||||
// Since we removed content offsets, calculate contentW directly from the scale and logical size
|
||||
float contentW = LOGICAL_W * logicalScale;
|
||||
bool isSmall = (contentW < 700.0f);
|
||||
float btnW = isSmall ? (LOGICAL_W * 0.4f) : 300.0f;
|
||||
float btnH = isSmall ? 60.0f : 70.0f;
|
||||
|
||||
@ -3,12 +3,18 @@
|
||||
#include "gameplay/Game.h"
|
||||
#include "gameplay/LineEffect.h"
|
||||
#include "persistence/Scores.h"
|
||||
#include "../audio/Audio.h"
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
PlayingState::PlayingState(StateContext& ctx) : State(ctx) {}
|
||||
|
||||
void PlayingState::onEnter() {
|
||||
// Nothing yet; main still owns game creation
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[PLAYING] Entering Playing state");
|
||||
// Initialize the game with the selected starting level
|
||||
if (ctx.game && ctx.startLevelSelection) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[PLAYING] Resetting game with level %d", *ctx.startLevelSelection);
|
||||
ctx.game->reset(*ctx.startLevelSelection);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayingState::onExit() {
|
||||
@ -54,12 +60,40 @@ void PlayingState::handleEvent(const SDL_Event& e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Other gameplay keys already registered by main's Playing handler for now
|
||||
// Tetris controls (only when not paused)
|
||||
if (!ctx.game->isPaused()) {
|
||||
// Rotation (still event-based for precise timing)
|
||||
if (e.key.scancode == SDL_SCANCODE_UP || e.key.scancode == SDL_SCANCODE_W ||
|
||||
e.key.scancode == SDL_SCANCODE_Z) {
|
||||
ctx.game->rotate(1); // Clockwise rotation
|
||||
return;
|
||||
}
|
||||
if (e.key.scancode == SDL_SCANCODE_X) {
|
||||
ctx.game->rotate(-1); // Counter-clockwise rotation
|
||||
return;
|
||||
}
|
||||
|
||||
// Hard drop (space)
|
||||
if (e.key.scancode == SDL_SCANCODE_SPACE) {
|
||||
ctx.game->hardDrop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Left/Right movement and soft drop are now handled by
|
||||
// ApplicationManager's update handler for proper DAS/ARR timing
|
||||
}
|
||||
|
||||
void PlayingState::update(double frameMs) {
|
||||
if (!ctx.game) return;
|
||||
|
||||
static bool debugPrinted = false;
|
||||
if (!debugPrinted) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "[PLAYING] Starting updates, frameMs=%.2f, paused=%d", frameMs, ctx.game->isPaused());
|
||||
debugPrinted = true;
|
||||
}
|
||||
|
||||
// forward per-frame gameplay updates (gravity, elapsed)
|
||||
if (!ctx.game->isPaused()) {
|
||||
ctx.game->tickGravity(frameMs);
|
||||
@ -71,11 +105,8 @@ void PlayingState::update(double frameMs) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.game->isGameOver()) {
|
||||
if (ctx.scores) ctx.scores->submit(ctx.game->score(), ctx.game->lines(), ctx.game->level(), ctx.game->elapsed());
|
||||
// Transitioning state must be done by the owner (main via StateManager hooks). We can't set state here.
|
||||
}
|
||||
|
||||
// Note: Game over detection and state transition is now handled by ApplicationManager
|
||||
}
|
||||
|
||||
void PlayingState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP) {
|
||||
|
||||
@ -40,6 +40,8 @@ struct StateContext {
|
||||
// Audio / SFX - forward declared types in main
|
||||
// Pointers to booleans/flags used by multiple states
|
||||
bool* musicEnabled = nullptr;
|
||||
bool* musicStarted = nullptr;
|
||||
bool* musicLoaded = nullptr;
|
||||
int* startLevelSelection = nullptr;
|
||||
int* hoveredButton = nullptr;
|
||||
// Menu popups (exposed from main)
|
||||
|
||||
Reference in New Issue
Block a user