1 /************************************************************************************
2 
3 	AstroMenace
4 	Hardcore 3D space scroll-shooter with spaceship upgrade possibilities.
5 	Copyright (c) 2006-2019 Mikhail Kurinnoi, Viewizard
6 
7 
8 	AstroMenace is free software: you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation, either version 3 of the License, or
11 	(at your option) any later version.
12 
13 	AstroMenace is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with AstroMenace. If not, see <https://www.gnu.org/licenses/>.
20 
21 
22 	Website: https://viewizard.com/
23 	Project: https://github.com/viewizard/astromenace
24 	E-mail: viewizard@viewizard.com
25 
26 *************************************************************************************/
27 
28 // TODO translate comments
29 
30 // TODO NeedCheck in CheckMouseKeybJState() should be moved to enumeration
31 
32 #include "../core/core.h"
33 #include "../enum.h"
34 #include "../config/config.h"
35 #include "../platform/platform.h"
36 #include "../assets/audio.h"
37 #include "../assets/texture.h"
38 #include "../ui/cursor.h"
39 #include "../command.h"
40 #include "../game.h" // FIXME "game.h" should be replaced by individual headers
41 
42 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
43 namespace viewizard {
44 namespace astromenace {
45 
46 int ButQuant = 10;
47 float But[10] =
48 {1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f};
49 
50 int NeedCheck = 0;
51 float LastTimeBut = 0.0f;
52 
53 
54 
ReservedKeys(int Key)55 static bool ReservedKeys(int Key)
56 {
57 	switch (Key) {
58 	case SDLK_ESCAPE:
59 		NeedCheck = 0;
60 		// don't remove this code duplication for now, don't use "[[fallthrough]];" (since C++17)
61 		// or "[[gnu::fallthrough]];" here for supress GCC7 warnings, since this produce another
62 		// warnings on old compiller versions
63 		vw_SetKeyStatus(Key, false);
64 		return true;
65 	case SDLK_F1:
66 	case SDLK_F2:
67 	case SDLK_F3:
68 	case SDLK_F4:
69 	case SDLK_F5:
70 	case SDLK_F6:
71 	case SDLK_F7:
72 	case SDLK_F8:
73 	case SDLK_F9:
74 	case SDLK_F10:
75 	case SDLK_F11:
76 	case SDLK_F12:
77 	case SDLK_F13:
78 	case SDLK_F14:
79 	case SDLK_F15:
80 	case SDLK_F16:
81 	case SDLK_F17:
82 	case SDLK_F18:
83 	case SDLK_F19:
84 	case SDLK_F20:
85 	case SDLK_F21:
86 	case SDLK_F22:
87 	case SDLK_F23:
88 	case SDLK_F24:
89 	case SDLK_PRINTSCREEN:
90 		vw_SetKeyStatus(Key, false);
91 		return true;
92 	}
93 
94 	return false;
95 }
96 
97 
98 // проверка, выбрали что-то или нет
CheckMouseKeybJState()99 void CheckMouseKeybJState()
100 {
101 	// проверяем, нужно ли вытягивать что-то или нет...
102 	if (!isDialogBoxDrawing())
103 		if (NeedCheck > 0) {
104 
105 			// клавиатура
106 			if ((NeedCheck > 0 && NeedCheck <= 6) || NeedCheck == 100)
107 				for (int k = 0; k < vw_GetKeyStateArraySize(); k++) {
108 					int i = SDL_GetKeyFromScancode((SDL_Scancode)k);
109 					if (vw_GetKeyStatus(i) &&
110 					    !ReservedKeys(i))
111 						if (SDL_GetKeyName(i)) { // если мы играем с этой кнопкой
112 							switch (NeedCheck) {
113 							case 1:
114 								ChangeGameConfig().KeyBoardUp = i;
115 								break;
116 							case 2:
117 								ChangeGameConfig().KeyBoardDown = i;
118 								break;
119 							case 3:
120 								ChangeGameConfig().KeyBoardLeft = i;
121 								break;
122 							case 4:
123 								ChangeGameConfig().KeyBoardRight = i;
124 								break;
125 							case 5:
126 								ChangeGameConfig().KeyBoardPrimary = i;
127 								break;
128 							case 6:
129 								ChangeGameConfig().KeyBoardSecondary = i;
130 								break;
131 							case 100:
132 								NewWeaponControlType = 1;
133 								NewWeaponControlTypeData = i;
134 								break;
135 							}
136 
137 							vw_SetKeyStatus(i, false);
138 							NeedCheck = 0;
139 						}
140 				}
141 
142 
143 			// мышка
144 			if ((NeedCheck >= 7 && NeedCheck <= 8) || NeedCheck == 100) {
145 				// note, SDL provide button's number that starts from 1
146 				for (unsigned i = 1; i <= vw_GetMaxMouseButtonNum(); i++)
147 					if (vw_GetMouseButtonStatus(i)) {
148 						switch (NeedCheck) {
149 						case 7:
150 							ChangeGameConfig().MousePrimary = i;
151 							break;
152 						case 8:
153 							ChangeGameConfig().MouseSecondary = i;
154 							break;
155 						case 100:
156 							NewWeaponControlType = 2;
157 							NewWeaponControlTypeData = i;
158 							break;
159 						}
160 						NeedCheck = 0;
161 						vw_GetMouseLeftClick(true);
162 					}
163 			}
164 
165 
166 			// джойстик
167 			if (isJoystickAvailable())
168 				if ((NeedCheck >= 9 && NeedCheck <= 10) || NeedCheck == 100) {
169 					for (int i = 0; i < GetJoystickButtonsQuantity(); i++)
170 						if (GetJoystickButton(i)) {
171 							switch (NeedCheck) {
172 							case 9:
173 								ChangeGameConfig().JoystickPrimary = i;
174 								break;
175 							case 10:
176 								ChangeGameConfig().JoystickSecondary = i;
177 								break;
178 							case 100:
179 								NewWeaponControlType = 3;
180 								NewWeaponControlTypeData = i;
181 								break;
182 							}
183 							NeedCheck = 0;
184 							SetJoystickButton(i, false);
185 							vw_GetMouseLeftClick(true);
186 						}
187 				}
188 
189 
190 			// если нажали Esc - возвращаем старые настройки выбора текущей кнопки
191 			if (vw_GetKeyStatus(SDLK_ESCAPE)) {
192 				vw_SetKeyStatus(SDLK_ESCAPE, false);
193 				NeedCheck = 0;
194 			}
195 		}
196 
197 	// мерцание кнопок, ставим сюда, чтобы не тягать его везде
198 	float Delta = vw_GetTimeThread(0) - LastTimeBut;
199 	for (int i=0; i<ButQuant; i++) {
200 		if (But[i] > 0.3f) But[i] -= 2.0f*Delta;
201 		if (But[i] < 0.3f) But[i] = 1.0f;
202 	}
203 	LastTimeBut = vw_GetTimeThread(0);
204 }
205 
206 
207 
CheckKeysBeforeExit()208 void CheckKeysBeforeExit()
209 {
210 	if (!GameConfig().KeyBoardUp)
211 		ChangeGameConfig().KeyBoardUp = SDLK_UP;
212 	if (!GameConfig().KeyBoardDown)
213 		ChangeGameConfig().KeyBoardDown = SDLK_DOWN;
214 	if (!GameConfig().KeyBoardLeft)
215 		ChangeGameConfig().KeyBoardLeft = SDLK_LEFT;
216 	if (!GameConfig().KeyBoardRight)
217 		ChangeGameConfig().KeyBoardRight = SDLK_RIGHT;
218 	if (!GameConfig().KeyBoardPrimary)
219 		ChangeGameConfig().KeyBoardPrimary = SDLK_LCTRL;
220 	if (!GameConfig().KeyBoardSecondary)
221 		ChangeGameConfig().KeyBoardSecondary = SDLK_SPACE;
222 	if (!GameConfig().MousePrimary)
223 		ChangeGameConfig().MousePrimary = SDL_BUTTON_LEFT;
224 	if (!GameConfig().MouseSecondary)
225 		ChangeGameConfig().MouseSecondary = SDL_BUTTON_RIGHT;
226 	NeedCheck = 0;
227 	for (int i = 0; i < ButQuant; i++) {
228 		But[i] = 1.0f;
229 	}
230 }
231 
232 
233 
234 
ConfControlMenu(float ContentTransp,float & ButtonTransp1,float & LastButtonUpdateTime1)235 void ConfControlMenu(float ContentTransp, float &ButtonTransp1, float &LastButtonUpdateTime1)
236 {
237 	// проверяем, нужно ли вытягивать что-то или нет...
238 	CheckMouseKeybJState();
239 
240 
241 	sRECT SrcRect, DstRect;
242 	SrcRect(0, 0, 2, 2);
243 	DstRect(0, 0, GameConfig().InternalWidth, 768);
244 	vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/blackpoint.tga"), true, 0.5f * ContentTransp);
245 
246 
247 
248 
249 
250 
251 
252 	int X1 = GameConfig().InternalWidth / 2 - 375;
253 	int Y1 = 65;
254 	int Prir1 = 55;
255 
256 
257 
258 
259 
260 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Joystick DeadZone"));
261 	if (DrawButton128_2(X1+300, Y1-6, vw_GetTextUTF32("Decrease"), ContentTransp, GameConfig().JoystickDeadZone == 0)) {
262 		ChangeGameConfig().JoystickDeadZone--;
263 		if (GameConfig().JoystickDeadZone < 0)
264 			ChangeGameConfig().JoystickDeadZone = 0;
265 	}
266 	if (DrawButton128_2(X1+616, Y1-6, vw_GetTextUTF32("Increase"), ContentTransp, GameConfig().JoystickDeadZone == 10)) {
267 		ChangeGameConfig().JoystickDeadZone++;
268 		if (GameConfig().JoystickDeadZone > 10)
269 			ChangeGameConfig().JoystickDeadZone = 10;
270 	}
271 	for (int i=0; i<10; i++) {
272 		SrcRect(0,0,16,32);
273 		DstRect(X1+443+16*i,Y1-4,X1+443+16+16*i,Y1+32-4);
274 		if (vw_MouseOverRect(DstRect)) {
275 			SetCursorStatus(eCursorStatus::ActionAllowed);
276 			if (vw_GetMouseLeftClick(true)) {
277 				ChangeGameConfig().JoystickDeadZone = i + 1;
278 				PlayMenuSFX(eMenuSFX::Click, 1.0f);
279 			}
280 		}
281 		if (GameConfig().JoystickDeadZone > i)
282 			vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/perc.tga"), true, ContentTransp);
283 		else
284 			vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/perc_none.tga"), true, ContentTransp);
285 	}
286 
287 
288 
289 
290 
291 	Y1 += Prir1;
292 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Control Sensitivity"));
293 	if (DrawButton128_2(X1+300, Y1-6, vw_GetTextUTF32("Decrease"), ContentTransp, GameConfig().ControlSensivity == 1)) {
294 		ChangeGameConfig().ControlSensivity--;
295 		if (GameConfig().ControlSensivity < 1)
296 			ChangeGameConfig().ControlSensivity = 1;
297 	}
298 	if (DrawButton128_2(X1+616, Y1-6, vw_GetTextUTF32("Increase"), ContentTransp, GameConfig().ControlSensivity == 10)) {
299 		ChangeGameConfig().ControlSensivity++;
300 		if (GameConfig().ControlSensivity > 10)
301 			ChangeGameConfig().ControlSensivity = 10;
302 	}
303 	for (int i=0; i<10; i++) {
304 		SrcRect(0,0,16,32);
305 		DstRect(X1+443+16*i,Y1-4,X1+443+16+16*i,Y1+32-4);
306 		if (vw_MouseOverRect(DstRect)) {
307 			SetCursorStatus(eCursorStatus::ActionAllowed);
308 			if (vw_GetMouseLeftClick(true)) {
309 				ChangeGameConfig().ControlSensivity = i + 1;
310 				PlayMenuSFX(eMenuSFX::Click, 1.0f);
311 			}
312 		}
313 		if (GameConfig().ControlSensivity > i)
314 			vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/perc.tga"), true, ContentTransp);
315 		else
316 			vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/perc_none.tga"), true, ContentTransp);
317 	}
318 
319 
320 
321 
322 
323 
324 
325 
326 
327 
328 
329 
330 
331 	Y1 += Prir1;
332 	int SizeI1 = vw_TextWidthUTF32(vw_GetTextUTF32("MOUSE"));
333 	int SizeI = SizeI1 > 130 ? -15 : (100-SizeI1)/2;
334 	vw_DrawTextUTF32(X1+315+SizeI, Y1, SizeI1 > 130 ? -130 : 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("MOUSE"));
335 	SizeI1 = vw_TextWidthUTF32(vw_GetTextUTF32("KEYBOARD"));
336 	SizeI = SizeI1 > 130 ? 10 : (150-SizeI1)/2;
337 	vw_DrawTextUTF32(X1+446+SizeI, Y1, SizeI1 > 130 ? -130 : 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("KEYBOARD"));
338 	SizeI1 = vw_TextWidthUTF32(vw_GetTextUTF32("JOYSTICK"));
339 	SizeI = SizeI1 > 130 ? 10 : (150-SizeI1)/2;
340 	vw_DrawTextUTF32(X1+605+SizeI, Y1, SizeI1 > 130 ? -130 : 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("JOYSTICK"));
341 
342 
343 	Y1 += Prir1;
344 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Primary Attack"));
345 	float Transp = 1.0f;
346 	bool Off = false;
347 	std::string ButtonName = MouseButtonName(GameConfig().MousePrimary);
348 	if (NeedCheck == 7) {
349 		Transp = But[6];
350 		Off = true;
351 		ButtonName = "?";
352 	};
353 	if (DrawButton128_2(X1+300, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
354 		if (NeedCheck == 0) {
355 			NeedCheck = 7;
356 			vw_ResetMouseButtons();
357 		}
358 
359 	Transp = 1.0f;
360 	Off = false;
361 	ButtonName = SDL_GetKeyName(GameConfig().KeyBoardPrimary);
362 	if (NeedCheck == 5) {
363 		Transp = But[4];
364 		Off = true;
365 		ButtonName = "?";
366 	};
367 	if (DrawButton128_2(X1+458, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
368 		if (NeedCheck == 0)
369 			NeedCheck = 5;
370 
371 	Transp = 1.0f;
372 	Off = false;
373 	ButtonName = JoystickButtonName(GameConfig().JoystickPrimary);
374 	if (NeedCheck == 9) {
375 		Transp = But[8];
376 		Off = true;
377 		ButtonName = "?";
378 	};
379 	if (DrawButton128_2(X1+616, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, !isJoystickAvailable() || Off))
380 		if (NeedCheck == 0) {
381 			NeedCheck = 9;
382 			for (int i = 0; i < GetJoystickButtonsQuantity(); i++) {
383 				SetJoystickButton(i, false);
384 			}
385 		}
386 
387 
388 
389 	Y1 += Prir1;
390 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Secondary Attack"));
391 	Transp = 1.0f;
392 	Off = false;
393 	ButtonName = MouseButtonName(GameConfig().MouseSecondary);
394 	if (NeedCheck == 8) {
395 		Transp = But[7];
396 		Off = true;
397 		ButtonName = "?";
398 	};
399 	if (DrawButton128_2(X1+300, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
400 		if (NeedCheck == 0) {
401 			NeedCheck = 8;
402 			vw_ResetMouseButtons();
403 		}
404 
405 	Transp = 1.0f;
406 	Off = false;
407 	ButtonName = SDL_GetKeyName(GameConfig().KeyBoardSecondary);
408 	if (NeedCheck == 6) {
409 		Transp = But[5];
410 		Off = true;
411 		ButtonName = "?";
412 	};
413 	if (DrawButton128_2(X1+458, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
414 		if (NeedCheck == 0)
415 			NeedCheck = 6;
416 
417 	Transp = 1.0f;
418 	Off = false;
419 	ButtonName = JoystickButtonName(GameConfig().JoystickSecondary);
420 	if (NeedCheck == 10) {
421 		Transp = But[9];
422 		Off = true;
423 		ButtonName = "?";
424 	};
425 	if (DrawButton128_2(X1+616, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, !isJoystickAvailable() || Off))
426 		if (NeedCheck == 0) {
427 			NeedCheck = 10;
428 			for (int i = 0; i < GetJoystickButtonsQuantity(); i++) {
429 				SetJoystickButton(i, false);
430 			}
431 		}
432 
433 
434 
435 
436 	Y1 += Prir1;
437 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Move Forward"));
438 	Transp = 1.0f;
439 	Off = false;
440 	ButtonName = SDL_GetKeyName(GameConfig().KeyBoardUp);
441 	if (NeedCheck == 1) {
442 		Transp = But[0];
443 		Off = true;
444 		ButtonName = "?";
445 	};
446 	if (DrawButton128_2(X1+458, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
447 		if (NeedCheck == 0) NeedCheck = 1;
448 
449 	Y1 += Prir1;
450 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Move Backward"));
451 	Transp = 1.0f;
452 	Off = false;
453 	ButtonName = SDL_GetKeyName(GameConfig().KeyBoardDown);
454 	if (NeedCheck == 2) {
455 		Transp = But[1];
456 		Off = true;
457 		ButtonName = "?";
458 	};
459 	if (DrawButton128_2(X1+458, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
460 		if (NeedCheck == 0)
461 			NeedCheck = 2;
462 
463 	Y1 += Prir1;
464 	vw_DrawTextUTF32(X1, Y1, -280, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Move Left"));
465 	Transp = 1.0f;
466 	Off = false;
467 	ButtonName = SDL_GetKeyName(GameConfig().KeyBoardLeft);
468 	if (NeedCheck == 3) {
469 		Transp = But[2];
470 		Off = true;
471 		ButtonName = "?";
472 	};
473 	if (DrawButton128_2(X1+458, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
474 		if (NeedCheck == 0)
475 			NeedCheck = 3;
476 
477 	Y1 += Prir1;
478 	vw_DrawTextUTF32(X1, Y1, -280, 0,1.0f, sRGBCOLOR{eRGBCOLOR::white}, ContentTransp, vw_GetTextUTF32("Move Right"));
479 	Transp = 1.0f;
480 	Off = false;
481 	ButtonName = SDL_GetKeyName(GameConfig().KeyBoardRight);
482 	if (NeedCheck == 4) {
483 		Transp = But[3];
484 		Off = true;
485 		ButtonName = "?";
486 	};
487 	if (DrawButton128_2(X1+458, Y1-6, ConvertUTF8.from_bytes(ButtonName), Transp*ContentTransp, Off))
488 		if (NeedCheck == 0)
489 			NeedCheck = 4;
490 
491 
492 
493 
494 
495 
496 
497 	int Prir = 100;
498 	int X;
499 	int Y = 165+Prir*4;
500 
501 
502 	X = GameConfig().InternalWidth / 2 - 366;
503 	if (DrawButton200_2(X,Y+28, vw_GetTextUTF32("Advanced"), ContentTransp, false)) {
504 		if (MenuStatus == eMenuStatus::GAME) {
505 			SetOptionsMenu(eMenuStatus::OPTIONS_ADVANCED);
506 			GameMenuStatus = eGameMenuStatus::OPTIONS_ADVANCED;
507 		} else
508 			cCommand::GetInstance().Set(eCommand::SWITCH_TO_OPTIONS_ADVANCED);
509 		CheckKeysBeforeExit();
510 	}
511 
512 
513 	X = GameConfig().InternalWidth / 2 - 100;
514 	if (DrawButton200_2(X,Y+28, vw_GetTextUTF32("Video & Audio"), ContentTransp, false)) {
515 		if (MenuStatus == eMenuStatus::GAME) {
516 			SetOptionsMenu(eMenuStatus::OPTIONS);
517 			GameMenuStatus = eGameMenuStatus::OPTIONS;
518 		} else
519 			cCommand::GetInstance().Set(eCommand::SWITCH_TO_OPTIONS);
520 		CheckKeysBeforeExit();
521 	}
522 
523 
524 	X = GameConfig().InternalWidth / 2 + 166;
525 	if (DrawButton200_2(X,Y+28, vw_GetTextUTF32("Interface"), ContentTransp, false)) {
526 		if (MenuStatus == eMenuStatus::GAME) {
527 			SetOptionsMenu(eMenuStatus::INTERFACE);
528 			GameMenuStatus = eGameMenuStatus::INTERFACE;
529 		} else
530 			cCommand::GetInstance().Set(eCommand::SWITCH_TO_INTERFACE);
531 		CheckKeysBeforeExit();
532 	}
533 
534 
535 
536 
537 	X = (GameConfig().InternalWidth - 384) / 2;
538 	Y = Y+Prir;
539 	if (MenuStatus == eMenuStatus::GAME) {
540 		if (DrawButton384(X,Y, vw_GetTextUTF32("GAME MENU"), ContentTransp, ButtonTransp1, LastButtonUpdateTime1)) {
541 			GameMenuStatus = eGameMenuStatus::GAME_MENU;
542 			CheckKeysBeforeExit();
543 		}
544 	} else {
545 		if (DrawButton384(X,Y, vw_GetTextUTF32("MAIN MENU"), ContentTransp, ButtonTransp1, LastButtonUpdateTime1)) {
546 			cCommand::GetInstance().Set(eCommand::SWITCH_TO_MAIN_MENU);
547 			CheckKeysBeforeExit();
548 		}
549 	}
550 
551 }
552 
553 } // astromenace namespace
554 } // viewizard namespace
555