Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Unreleased

### Added
- `--theme-menu` starts the game directly on the theme selection screen (Configure -> Themes)

### Removed
### Changed

Expand Down
5 changes: 4 additions & 1 deletion man/blockattack.man
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BLOCKATTACK "6" "October 2025" "blockattack 2.11.0-SNAPSHOT" "Games"
.TH BLOCKATTACK "6" "September 2026" "blockattack 2.11.0-SNAPSHOT" "Games"
.SH NAME
blockattack \- a puzzle game inspired by Tetris Attack
.SH SYNOPSIS
Expand Down Expand Up @@ -52,6 +52,9 @@ Start the sprite editor/browser
\fB\-\-puzzle\-editor\fR
Start the build in puzzle editor
.TP
\fB\-\-theme\-menu\fR
Go directly to the theme selection screen
.TP
\fB\-\-puzzle\-level\-file\fR arg
Sets the default puzzle file to load
.TP
Expand Down
3 changes: 2 additions & 1 deletion source/code/BlockGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,10 @@ void BlockGame::putSampleBlocks() {
for (size_t j = 6; j < 9; j++) {
board[i][j] = GARBAGE+1;
}
for (size_t j = 9; j < 12; j++) {
for (size_t j = 9; j < 11; j++) {
board[i][j] = GARBAGE+2;
}
board[i][11] = GARBAGE_GRAY*GARBAGE;
}
}

Expand Down
32 changes: 17 additions & 15 deletions source/code/BlockGameSdl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ class BlockGameSdl : public BlockGame {

//Draws all the bricks to the board (including garbage)
void PaintBricks() const {
const GarbageData& garbageSet = globalData.theme.garbage;
const sago::SagoSpriteHolder& sprites = *globalData.spriteHolder;
for (int i=0; i<13; ++i) {
for (int j=0; j<6; ++j) {
int basicBrick = board[j][i]%10; //The basic brick, stored on the least significant digit
Expand Down Expand Up @@ -279,51 +281,51 @@ class BlockGameSdl : public BlockGame {
under = board[j][i-1];
}
if ((left == number)&&(right == number)&&(over == number)&&(under == number)) {
DrawImgBoardBounded(globalData.garbageFill, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.fill), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left != number)&&(right == number)&&(over == number)&&(under == number)) {
DrawImgBoardBounded(globalData.garbageL, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.l), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right != number)&&(over == number)&&(under == number)) {
DrawImgBoardBounded(globalData.garbageR, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.r), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right == number)&&(over != number)&&(under == number)) {
DrawImgBoardBounded(globalData.garbageT, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.t), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right == number)&&(over == number)&&(under != number)) {
DrawImgBoardBounded(globalData.garbageB, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.b), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left != number)&&(right == number)&&(over != number)&&(under == number)) {
DrawImgBoardBounded(globalData.garbageTL, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.tl), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left != number)&&(right == number)&&(over == number)&&(under != number)) {
DrawImgBoardBounded(globalData.garbageBL, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.bl), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right != number)&&(over != number)&&(under == number)) {
DrawImgBoardBounded(globalData.garbageTR, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.tr), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right != number)&&(over == number)&&(under != number)) {
DrawImgBoardBounded(globalData.garbageBR, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.br), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right != number)&&(over != number)&&(under != number)) {
DrawImgBoardBounded(globalData.garbageMR, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.mr), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left == number)&&(right == number)&&(over != number)&&(under != number)) {
DrawImgBoardBounded(globalData.garbageM, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.m), j*bsize, bsize*12-i*bsize-pixels);
}
if ((left != number)&&(right == number)&&(over != number)&&(under != number)) {
DrawImgBoardBounded(globalData.garbageML, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.ml), j*bsize, bsize*12-i*bsize-pixels);
}
}
if ((board[j][i]/1000000)%10==2) {
if (j==0) {
DrawImgBoardBounded(globalData.garbageGML, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.gml), j*bsize, bsize*12-i*bsize-pixels);
}
else if (j==5) {
DrawImgBoardBounded(globalData.garbageGMR, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.gmr), j*bsize, bsize*12-i*bsize-pixels);
}
else {
DrawImgBoardBounded(globalData.garbageGM, j*bsize, bsize*12-i*bsize-pixels);
DrawImgBoardBounded(sprites.GetSprite(garbageSet.gm), j*bsize, bsize*12-i*bsize-pixels);
}
}
}
Expand Down
15 changes: 0 additions & 15 deletions source/code/global.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,6 @@ struct GlobalData {
sago::SoundHandler counterChunk; //When counting down
sago::SoundHandler counterFinalChunk;

sago::SagoSprite garbageTL; //the Garbage Blocks
sago::SagoSprite garbageT;
sago::SagoSprite garbageTR;
sago::SagoSprite garbageR;
sago::SagoSprite garbageBR;
sago::SagoSprite garbageB;
sago::SagoSprite garbageBL;
sago::SagoSprite garbageL;
sago::SagoSprite garbageFill;
sago::SagoSprite garbageM;
sago::SagoSprite garbageML;
sago::SagoSprite garbageMR;
sago::SagoSprite garbageGM;
sago::SagoSprite garbageGML;
sago::SagoSprite garbageGMR;
sago::SagoSprite transCover; //The transperant block, covers the upcomming
sago::SagoSprite bSkip;
sago::SagoSprite bRetry;
Expand Down
37 changes: 7 additions & 30 deletions source/code/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Source information and contacts persons can be found at

#include "editor/SagoTextureSelector.hpp"
#include "puzzle_editor/PuzzleEditorState.hpp"
#include "theme_editor/ThemeEditorState.hpp"
#include "menudef_themes.hpp"
#include "SagoImGui.hpp"

/*******************************************************************************
Expand Down Expand Up @@ -172,21 +172,6 @@ static int InitImages(sago::SagoSpriteHolder& holder) {
globalData.iLevelCheckBoxMarked = holder.GetSprite("i_level_check_box_marked");
globalData.iCheckBoxArea = holder.GetSprite("i_check_box_area");
globalData.boardBackBack = holder.GetSprite("board_back_back");
globalData.garbageTL = holder.GetSprite("garbage_tl");
globalData.garbageT = holder.GetSprite("garbage_t");
globalData.garbageTR = holder.GetSprite("garbage_tr");
globalData.garbageR = holder.GetSprite("garbage_r");
globalData.garbageBR = holder.GetSprite("garbage_br");
globalData.garbageB = holder.GetSprite("garbage_b");
globalData.garbageBL = holder.GetSprite("garbage_bl");
globalData.garbageL = holder.GetSprite("garbage_l");
globalData.garbageFill = holder.GetSprite("garbage_fill");
globalData.garbageML = holder.GetSprite("garbage_ml");
globalData.garbageM = holder.GetSprite("garbage_m");
globalData.garbageMR = holder.GetSprite("garbage_mr");
globalData.garbageGM = holder.GetSprite("garbage_gm");
globalData.garbageGML = holder.GetSprite("garbage_gml");
globalData.garbageGMR = holder.GetSprite("garbage_gmr");
globalData.transCover = holder.GetSprite("trans_cover");
bExit = holder.GetSprite("b_exit");
globalData.bSkip = holder.GetSprite("b_blank");
Expand Down Expand Up @@ -948,7 +933,7 @@ static void ParseArguments(int argc, char* argv[], globalConfig& conf) {
("always-sixteen-nine", "Use 16:9 format even in Window mode")
("editor", "Start the sprite editor/browser")
("puzzle-editor", "Start the build in puzzle editor")
("theme-editor", "Start the theme editor")
("theme-menu", "Go directly to the theme selection screen")
("puzzle-level-file", boost::program_options::value<std::string>(), "Sets the default puzzle file to load")
("puzzle-single-level", boost::program_options::value<int>(), "Start the specific puzzle level directly")
#ifdef REPLAY_IMPLEMENTED
Expand Down Expand Up @@ -1050,8 +1035,8 @@ static void ParseArguments(int argc, char* argv[], globalConfig& conf) {
if (vm.count("puzzle-editor")) {
puzzleEditor = true;
}
if (vm.count("theme-editor")) {
themeEditor = true;
if (vm.count("theme-menu")) {
themeMenu = true;
}
if (vm.count("puzzle-level-file")) {
conf.puzzleName = vm["puzzle-level-file"].as<std::string>();
Expand Down Expand Up @@ -1358,17 +1343,6 @@ int main(int argc, char* argv[]) {
RunImGuiGameState(s);
ImGui::SaveIniSettingsToDisk(imgui_inifile.c_str());
}
else if (themeEditor) {
InitImGui(sdlWindow, renderer, globalData.xsize, globalData.ysize);
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = nullptr;
std::string imgui_inifile = getPathToSaveFiles() + "/imgui_theme_editor.ini";
ImGui::LoadIniSettingsFromDisk(imgui_inifile.c_str());
ThemeEditorState s;
s.Init();
RunImGuiGameState(s);
ImGui::SaveIniSettingsToDisk(imgui_inifile.c_str());
}
else if (globalData.replayArgument.length()) {
ReplayPlayer rp;
RunGameState(rp);
Expand All @@ -1377,6 +1351,9 @@ int main(int argc, char* argv[]) {
if (!gameShutdownProperly) {
SafeModeMenu();
}
if (themeMenu) {
OpenThemesMenu();
}
//game loop
MainMenu();
}
Expand Down
2 changes: 1 addition & 1 deletion source/code/mainVars.inc
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ bool twoPlayers; //True if two playerImGui_ImplSDL2_ProcessEvent(&event);s ar
static bool singlePuzzle = false;
static bool editor = false;
static bool puzzleEditor = false;
static bool themeEditor = false;
static bool themeMenu = false;
static int singlePuzzleNr = 0;
static std::string singlePuzzleFile;

Expand Down
9 changes: 9 additions & 0 deletions source/code/menudef_themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ static void themesEditSwitchBorder() {
globalData.theme = themeToEdit;
}

static void themesEditSwitchGarbage() {
themeToEdit.garbage = ThemesGetNextGarbage(themeToEdit.garbage.name);
globalData.theme = themeToEdit;
}

static void themesEditSlot(int slot) {
ThemesMenu tem(globalData.screen, fmt::format(fmt::runtime(_("Edit custom theme {}")), slot), true);
size_t theme_index = ThemesGetNumber(fmt::format("custom_slot_{}", slot));
Expand All @@ -115,6 +120,10 @@ static void themesEditSlot(int slot) {
bSwitchBorder.setLabel(_("Switch border"));
bSwitchBorder.setAction(&themesEditSwitchBorder);
tem.addButton(&bSwitchBorder);
Button bSwitchGarbage;
bSwitchGarbage.setLabel(_("Switch garbage"));
bSwitchGarbage.setAction(&themesEditSwitchGarbage);
tem.addButton(&bSwitchGarbage);
themeBackup = globalData.theme;
themeToEdit = ThemesGet(theme_index);
globalData.theme = themeToEdit;
Expand Down
Loading