1 /*
2 ===========================================================================
3 blockattack - Block Attack - Rise of the Blocks
4 Copyright (C) 2005-2016 Poul Sander
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see http://www.gnu.org/licenses/
18
19 Source information and contacts persons can be found at
20 https://blockattack.net
21 ===========================================================================
22 */
23
24 #include "levelselect.hpp"
25 #include "SDL.h"
26 #include "common.h"
27 #include "global.hpp"
28 #include "puzzlehandler.hpp"
29 #include "stageclearhandler.hpp"
30 #include "MenuSystem.h"
31
32
33 static bool bMouseUp; //true if the mouse(1) is unpressed
34
35 static std::map<std::string, std::shared_ptr<sago::SagoTextField> > fieldCache;
36
getCachedText(const std::string & text)37 static sago::SagoTextField* getCachedText(const std::string& text) {
38 std::shared_ptr<sago::SagoTextField> ptr = fieldCache[text];
39 if (!ptr) {
40 std::shared_ptr<sago::SagoTextField> newText = std::make_shared<sago::SagoTextField>();
41 sagoTextSetBlueFont(*newText.get());
42 newText->SetText(text);
43 fieldCache[text] = newText;
44 }
45 return fieldCache[text].get();
46 }
47
Write(SDL_Renderer * target,int x,int y,const char * text)48 static void Write(SDL_Renderer* target, int x, int y, const char* text) {
49 getCachedText(text)->Draw(target, x, y);
50 }
51
52 //The function that allows the player to choose PuzzleLevel
PuzzleLevelSelect(int Type)53 int PuzzleLevelSelect(int Type) {
54 const int xplace = 200;
55 const int yplace = 300;
56 int levelNr = 0;
57 int oldmousex = 0;
58 int oldmousey = 0;
59 bool levelSelected = false;
60 int nrOfLevels = 0;
61 Uint32 totalScore = 0;
62 Uint32 totalTime = 0;
63 int selected = 0;
64 fieldCache.clear();
65
66 //Loads the levels, if they havn't been loaded:
67 if (Type == 0) {
68 LoadPuzzleStages();
69 nrOfLevels = PuzzleGetNumberOfPuzzles();
70 }
71 if (Type == 1) {
72 LoadStageClearStages();
73 totalScore = GetTotalScore();
74 totalTime = GetTotalTime();
75 nrOfLevels = GetNrOfLevels();
76 }
77
78 while (!levelSelected) {
79 SDL_Delay(1);
80 auto ticks = SDL_GetTicks();
81 DrawBackground(globalData.screen);
82 globalData.iCheckBoxArea.Draw(globalData.screen,ticks,xplace,yplace);
83 if (Type == 0) {
84 Write(globalData.screen, xplace+12,yplace+2,_("Select Puzzle") );
85 }
86 if (Type == 1) {
87 Write(globalData.screen, xplace+12,yplace+2, _("Stage Clear Level Select") );
88 }
89 //Now drow the fields you click in (and a V if clicked):
90 for (int i = 0; i < nrOfLevels; i++) {
91 globalData.iLevelCheckBox.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
92 if (i==selected) {
93 globalData.iLevelCheckBoxMarked.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
94 }
95 if (Type == 0 && PuzzleIsCleared(i)) {
96 globalData.iLevelCheck.Draw(globalData.screen,ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
97 }
98 if (Type == 1 && IsStageCleared(i)) {
99 globalData.iLevelCheck.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
100 }
101 }
102
103 SDL_Event event;
104 while ( SDL_PollEvent(&event) ) {
105 UpdateMouseCoordinates(event, globalData.mousex, globalData.mousey);
106
107 if ( event.type == SDL_QUIT ) {
108 Config::getInstance()->setShuttingDown(5);
109 levelNr = -1;
110 levelSelected = true;
111 }
112 if (isEscapeEvent(event)) {
113 levelNr = -1;
114 levelSelected = true;
115 }
116 if (isConfirmEvent(event)) {
117 levelNr = selected;
118 levelSelected = true;
119 }
120 if (isRightEvent(event)) {
121 ++selected;
122 if (selected >= nrOfLevels) {
123 selected = 0;
124 }
125 }
126 if (isLeftEvent(event)) {
127 --selected;
128 if (selected < 0) {
129 selected = nrOfLevels-1;
130 }
131 }
132 if (isDownEvent(event)) {
133 selected+=10;
134 if (selected >= nrOfLevels) {
135 selected-=10;
136 }
137 }
138 if (isUpEvent(event)) {
139 selected-=10;
140 if (selected < 0) {
141 selected+=10;
142 }
143 }
144 }
145
146 SDL_GetKeyboardState(nullptr);
147
148 if (globalData.mousex != oldmousex || globalData.mousey != oldmousey) {
149 int tmpSelected = -1;
150 int j;
151 for (j = 0; (tmpSelected == -1) && ( (j<nrOfLevels/10)||((j<nrOfLevels/10+1)&&(nrOfLevels%10 != 0)) ); j++) {
152 if ((60+j*50<globalData.mousey-yplace)&&(globalData.mousey-yplace<j*50+92)) {
153 tmpSelected = j*10;
154 }
155 }
156 if (tmpSelected != -1) {
157 for (int k = 0; (( (!(nrOfLevels%10) || k<nrOfLevels-10*(j-1)) )&&(k<10)); k++) {
158 if ((10+k*50<globalData.mousex-xplace)&&(globalData.mousex-xplace<k*50+42)) {
159 tmpSelected +=k;
160 selected = tmpSelected;
161 }
162 }
163 }
164 }
165 oldmousey = globalData.mousey;
166 oldmousex= globalData.mousex;
167
168 // If the mouse button is released, make bMouseUp equal true
169 if ( !(SDL_GetMouseState(nullptr, nullptr)&SDL_BUTTON(1)) ) {
170 bMouseUp=true;
171 }
172
173 if (SDL_GetMouseState(nullptr,nullptr)&SDL_BUTTON(1) && bMouseUp) {
174 bMouseUp = false;
175
176 int levelClicked = -1;
177 int i;
178 for (i = 0; (i<nrOfLevels/10)||((i<nrOfLevels/10+1)&&(nrOfLevels%10 != 0)); i++)
179 if ((60+i*50<globalData.mousey-yplace)&&(globalData.mousey-yplace<i*50+92)) {
180 levelClicked = i*10;
181 }
182 i++;
183 if (levelClicked != -1)
184 for (int j = 0; ((j<nrOfStageLevels%(i*10))&&(j<10)); j++)
185 if ((10+j*50<globalData.mousex-xplace)&&(globalData.mousex-xplace<j*50+42)) {
186 levelClicked +=j;
187 levelSelected = true;
188 levelNr = levelClicked;
189 }
190 }
191
192 if (Type == 1) {
193 std::string scoreString = SPrintStringF(_("Best score: %i"), GetStageScores(selected)) ;
194 std::string timeString = SPrintStringF(_("Time used: %s"),"-- : --");
195
196 if (GetStageTime(selected)>0) {
197 timeString = SPrintStringF(_("Time used: %d : %02d"), GetStageTime(selected)/1000/60, (GetStageTime(selected)/1000)%60);
198 }
199
200 Write(globalData.screen, 200,200,scoreString.c_str());
201 Write(globalData.screen, 200,250,timeString.c_str());
202 std::string totalString = SPrintStringF(_("Total score: %i in %i:%02i"), totalScore, totalTime/1000/60, ((totalTime/1000)%60) );
203 Write(globalData.screen, 200,600,totalString.c_str());
204 }
205
206 globalData.mouse.Draw(globalData.screen, SDL_GetTicks(), globalData.mousex, globalData.mousey);
207 SDL_RenderPresent(globalData.screen); //draws it all to the screen
208
209 }
210 DrawBackground(globalData.screen);
211 return levelNr;
212 }
213