1 /*
2  * Copyright 2011-2013 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis 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 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis 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 Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Code: Cyril Meynier
44 //
45 // Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved
46 
47 #include "gui/Menu.h"
48 
49 #include <cstdlib>
50 #include <sstream>
51 #include <iterator>
52 #include <iomanip>
53 
54 #include "Configure.h"
55 
56 #include "core/Application.h"
57 #include "core/Config.h"
58 #include "core/Core.h"
59 #include "core/GameTime.h"
60 #include "core/Localisation.h"
61 #include "core/Version.h"
62 
63 #include "game/Player.h"
64 
65 #include "gui/Credits.h"
66 #include "gui/Interface.h"
67 #include "gui/MenuPublic.h"
68 #include "gui/MenuWidgets.h"
69 #include "gui/Text.h"
70 #include "gui/TextManager.h"
71 
72 #include "graphics/Draw.h"
73 #include "graphics/Math.h"
74 #include "graphics/data/TextureContainer.h"
75 
76 #include "input/Input.h"
77 
78 #include "io/resource/PakReader.h"
79 #include "io/resource/ResourcePath.h"
80 #include "io/Screenshot.h"
81 #include "io/fs/Filesystem.h"
82 #include "io/log/Logger.h"
83 
84 #include "scene/LoadLevel.h"
85 #include "scene/ChangeLevel.h"
86 #include "scene/GameSound.h"
87 #include "scene/Light.h"
88 
89 #include "util/Unicode.h"
90 
91 extern TextManager * pTextManage;
92 extern Anglef ePlayerAngle;
93 extern float Xratio, Yratio;
94 extern ARX_INTERFACE_BOOK_MODE Book_Mode;
95 extern long START_NEW_QUEST;
96 extern long LASTBOOKBUTTON;
97 extern long BOOKBUTTON;
98 extern long OLD_FLYING_OVER;
99 extern long FLYING_OVER;
100 extern long BOOKZOOM;
101 extern long FRAME_COUNT;
102 extern float ARXTimeMenu;
103 extern float ARXOldTimeMenu;
104 extern long NEED_SPECIAL_RENDEREND;
105 extern bool bFadeInOut;
106 extern bool bFade;
107 extern int iFadeAction;
108 extern float fFadeInOut;
109 extern char SKIN_MOD;
110 extern char QUICK_MOD;
111 
112 
113 extern float ARXTimeMenu;
114 extern float ARXOldTimeMenu;
115 extern float ARXDiffTimeMenu;
116 
117 extern long	REQUEST_SPEECH_SKIP;
118 extern bool TRUE_PLAYER_MOUSELOOK_ON;
119 
120 extern TextureContainer * pTextureLoad;
121 
122 bool MENU_NoActiveWindow();
123 
124 //-----------------------------------------------------------------------------
125 // Exported global variables
126 
127 bool bQuickGenFirstClick = true;
128 ARX_MENU_DATA ARXmenu;
129 long REFUSE_GAME_RETURN = 0;
130 
131 static long SP_HEAD = 0;
132 
133 //-----------------------------------------------------------------------------
134 #define ARX_MENU_SIZE_Y 24
135 
136 
137 
ARX_MENU_CLICKSOUND()138 void ARX_MENU_CLICKSOUND() {
139 	ARX_SOUND_PlayMenu(SND_MENU_CLICK);
140 }
141 
142 //-----------------------------------------------------------------------------
143 // Menu Sounds
144 //-----------------------------------------------------------------------------
145 
ARX_MENU_LaunchAmb(const std::string & _lpszAmb)146 void ARX_MENU_LaunchAmb(const std::string & _lpszAmb) {
147 	ARX_SOUND_PlayMenuAmbiance(_lpszAmb);
148 }
149 
ARX_Menu_Resources_Create()150 void ARX_Menu_Resources_Create() {
151 
152 	delete ARXmenu.mda;
153 	ARXmenu.mda = new MENU_DYNAMIC_DATA();
154 	ARXmenu.mda->pTexCredits = TextureContainer::LoadUI("graph/interface/menus/menu_credits");
155 	ARXmenu.mda->BookBackground = TextureContainer::LoadUI("graph/interface/book/character_sheet/char_creation_bg", TextureContainer::NoColorKey);
156 
157 	ARXmenu.mda->flyover[BOOK_STRENGTH] = getLocalised("system_charsheet_strength");
158 	ARXmenu.mda->flyover[BOOK_MIND] = getLocalised("system_charsheet_intel");
159 	ARXmenu.mda->flyover[BOOK_DEXTERITY] = getLocalised("system_charsheet_dex");
160 	ARXmenu.mda->flyover[BOOK_CONSTITUTION] = getLocalised("system_charsheet_consti");
161 	ARXmenu.mda->flyover[BOOK_STEALTH] = getLocalised("system_charsheet_stealth");
162 	ARXmenu.mda->flyover[BOOK_MECANISM] = getLocalised("system_charsheet_mecanism");
163 	ARXmenu.mda->flyover[BOOK_INTUITION] = getLocalised("system_charsheet_intuition");
164 	ARXmenu.mda->flyover[BOOK_ETHERAL_LINK] = getLocalised("system_charsheet_etheral_link");
165 	ARXmenu.mda->flyover[BOOK_OBJECT_KNOWLEDGE] = getLocalised("system_charsheet_objknoledge");
166 	ARXmenu.mda->flyover[BOOK_CASTING] = getLocalised("system_charsheet_casting");
167 	ARXmenu.mda->flyover[BOOK_PROJECTILE] = getLocalised("system_charsheet_projectile");
168 	ARXmenu.mda->flyover[BOOK_CLOSE_COMBAT] = getLocalised("system_charsheet_closecombat");
169 	ARXmenu.mda->flyover[BOOK_DEFENSE] = getLocalised("system_charsheet_defense");
170 	ARXmenu.mda->flyover[BUTTON_QUICK_GENERATION] = getLocalised("system_charsheet_quickgenerate");
171 	ARXmenu.mda->flyover[BUTTON_DONE] = getLocalised("system_charsheet_done");
172 	ARXmenu.mda->flyover[BUTTON_SKIN] = getLocalised("system_charsheet_skin");
173 	ARXmenu.mda->flyover[WND_ATTRIBUTES] = getLocalised("system_charsheet_atributes");
174 	ARXmenu.mda->flyover[WND_SKILLS] = getLocalised("system_charsheet_skills");
175 	ARXmenu.mda->flyover[WND_STATUS] = getLocalised("system_charsheet_status");
176 	ARXmenu.mda->flyover[WND_LEVEL] = getLocalised("system_charsheet_level");
177 	ARXmenu.mda->flyover[WND_XP] = getLocalised("system_charsheet_xpoints");
178 	ARXmenu.mda->flyover[WND_HP] = getLocalised("system_charsheet_hp");
179 	ARXmenu.mda->flyover[WND_MANA] = getLocalised("system_charsheet_mana");
180 	ARXmenu.mda->flyover[WND_AC] = getLocalised("system_charsheet_ac");
181 	ARXmenu.mda->flyover[WND_RESIST_MAGIC] = getLocalised("system_charsheet_res_magic");
182 	ARXmenu.mda->flyover[WND_RESIST_POISON] = getLocalised("system_charsheet_res_poison");
183 	ARXmenu.mda->flyover[WND_DAMAGE] = getLocalised("system_charsheet_damage");
184 
185 	ARXmenu.mda->str_button_quickgen = getLocalised("system_charsheet_button_quickgen");
186 	ARXmenu.mda->str_button_skin = getLocalised("system_charsheet_button_skin");
187 	ARXmenu.mda->str_button_done = getLocalised("system_charsheet_button_done");
188 
189 
190 	// Load credits.
191 
192 	std::string creditsFile = "localisation/ucredits_" +  config.language + ".txt";
193 
194 	size_t creditsSize;
195 	char * credits = resources->readAlloc(creditsFile, creditsSize);
196 
197 	std::string englishCreditsFile;
198 	if(!credits) {
199 		// Fallback if there is no localised credits file
200 		englishCreditsFile = "localisation/ucredits_english.txt";
201 		credits = resources->readAlloc(englishCreditsFile, creditsSize);
202 	}
203 
204 	if(!credits) {
205 		if(!englishCreditsFile.empty() && englishCreditsFile != creditsFile) {
206 			LogWarning << "Unable to read credits files " << creditsFile
207 			           << " and " << englishCreditsFile;
208 		} else {
209 			LogWarning << "Unable to read credits file " << creditsFile;
210 		}
211 	} else {
212 
213 		LogDebug("Loaded credits file: " << creditsFile << " of size " << creditsSize);
214 
215 		ARXmenu.mda->credits = arx_credits;
216 
217 		ARXmenu.mda->credits += "\n\n\n~ORIGINAL ARX FATALIS CREDITS:\n\n\n";
218 
219 		ARXmenu.mda->credits += util::convertUTF16LEToUTF8(credits, credits + creditsSize);
220 
221 		LogDebug("Converted to UTF8 string of length " << ARXmenu.mda->credits.size());
222 
223 		free(credits);
224 	}
225 }
226 
ARX_Menu_Resources_Release(bool _bNoSound)227 void ARX_Menu_Resources_Release(bool _bNoSound) {
228 
229 	config.save();
230 
231 	if(ARXmenu.mda == NULL) {
232 		return;
233 	}
234 
235 	delete ARXmenu.mda->Background;
236 	delete ARXmenu.mda->BookBackground;
237 	delete ARXmenu.mda, ARXmenu.mda = NULL;
238 
239 	//Synchronize game mixers with menu mixers and switch between them
240 	if(_bNoSound) {
241 		ARXMenu_Options_Audio_ApplyGameVolumes();
242 	}
243 
244 	delete pTextureLoad, pTextureLoad = NULL;
245 }
246 
247 extern long NO_TIME_INIT;
248 
ARX_MENU_Clicked_QUIT()249 void ARX_MENU_Clicked_QUIT() {
250 
251 	if(REFUSE_GAME_RETURN) {
252 		return;
253 	}
254 
255 	ARX_Menu_Resources_Release();
256 	ARXmenu.currentmode = AMCM_OFF;
257 	if(!NO_TIME_INIT) {
258 		arxtime.resume();
259 	}
260 }
261 
ARX_MENU_Clicked_NEWQUEST()262 void ARX_MENU_Clicked_NEWQUEST() {
263 
264 	arxtime.resume();
265 
266 	REFUSE_GAME_RETURN = 1;
267 
268 	ARX_PLAYER_Start_New_Quest();
269 	Book_Mode = BOOKMODE_STATS;
270 	player.skin = 0;
271 	ePlayerAngle.b = -25.f;
272 	ARX_PLAYER_Restore_Skin();
273 	ARXmenu.currentmode = AMCM_NEWQUEST;
274 }
275 
ARX_MENU_NEW_QUEST_Clicked_QUIT()276 void ARX_MENU_NEW_QUEST_Clicked_QUIT() {
277 	START_NEW_QUEST = 1;
278 	REFUSE_GAME_RETURN = 0;
279 	NEED_SPECIAL_RENDEREND = 1;
280 	ARX_MENU_Clicked_QUIT();
281 }
282 
ARX_MENU_Clicked_CREDITS()283 void ARX_MENU_Clicked_CREDITS() {
284 	ARXmenu.currentmode = AMCM_CREDITS;
285 	Credits::reset();
286 	ARX_MENU_LaunchAmb(AMB_CREDITS);
287 }
288 
ARX_MENU_Clicked_QUIT_GAME()289 void ARX_MENU_Clicked_QUIT_GAME() {
290 	mainApp->Quit();
291 }
292 
ARX_MENU_Launch()293 void ARX_MENU_Launch() {
294 
295 	arxtime.pause();
296 
297 	//Synchronize menu mixers with game mixers and switch between them
298 	ARX_SOUND_MixerSwitch(ARX_SOUND_MixerGame, ARX_SOUND_MixerMenu);
299 
300 	ARX_SOUND_PlayMenuAmbiance(AMB_MENU);
301 	ARX_MENU_CLICKSOUND();
302 
303 	ARXmenu.currentmode = AMCM_MAIN;
304 	ARX_Menu_Resources_Create();
305 }
306 
ARX_Menu_Manage()307 void ARX_Menu_Manage() {
308 
309 	// looks for keys for each mode.
310 	switch (ARXmenu.currentmode)
311 	{
312 		case AMCM_OFF:
313 		{
314 			// Checks for ESC key
315 			if (GInput->isKeyPressedNowUnPressed(Keyboard::Key_Escape))
316 			{
317 				if (CINEMASCOPE)
318 				{
319 					if (!FADEDIR)	// Disabling ESC capture while fading in or out.
320 					{
321 						if (SendMsgToAllIO(SM_KEY_PRESSED,"")!=REFUSE)
322 						{
323 							REQUEST_SPEECH_SKIP=1;
324 						}
325 					}
326 				} else {
327 
328 					GRenderer->getSnapshot(savegame_thumbnail, 160, 100);
329 
330 					arxtime.pause();
331 					ARXTimeMenu=ARXOldTimeMenu=arxtime.get_updated();
332 					ARX_MENU_Launch();
333 					bFadeInOut=false;	//fade out
334 					bFade=true;			//active le fade
335 					TRUE_PLAYER_MOUSELOOK_ON = false;
336 
337 					ARX_PLAYER_PutPlayerInNormalStance(1);
338 				}
339 			}
340 		}
341 		break;
342 		case AMCM_NEWQUEST:
343 		{
344 			if (GInput->isKeyPressedNowUnPressed(Keyboard::Key_Escape)
345 					&&	! bFadeInOut // XS: Disabling ESC capture while fading in or out.
346 			   )
347 			{
348 				ARX_MENU_CLICKSOUND();
349 				ARXmenu.currentmode = AMCM_MAIN;
350 			}
351 		}
352 		break;
353 		case AMCM_MAIN:
354 
355 			if (GInput->isKeyPressedNowUnPressed(Keyboard::Key_Escape))
356 			{
357 				if ((MENU_NoActiveWindow())  && (!REFUSE_GAME_RETURN))
358 				{
359 					arxtime.resume();
360 					ARX_MENU_Clicked_QUIT();
361 				}
362 			}
363 
364 			break;
365 		case AMCM_CREDITS:
366 
367 			if ((GInput->isKeyPressedNowUnPressed(Keyboard::Key_Escape))
368 					|| (GInput->isKeyPressedNowUnPressed(Keyboard::Key_Spacebar)))
369 			{
370 				ARX_MENU_CLICKSOUND();
371 				bFadeInOut = true;	//fade out
372 				bFade = true;			//active le fade
373 				iFadeAction = AMCM_MAIN;
374 
375 				ARX_MENU_LaunchAmb(AMB_MENU);
376 			}
377 
378 			break;
379 		default:
380 			break;
381 	}
382 }
383 extern long PLAYER_INTERFACE_HIDE_COUNT;
384 //-----------------------------------------------------------------------------
385 // ARX Menu Rendering Func
386 // returns false if no menu needs to be displayed
387 //-----------------------------------------------------------------------------
ARX_Menu_Render()388 bool ARX_Menu_Render() {
389 
390 	if(ARXmenu.currentmode == AMCM_OFF) {
391 		return false;
392 	}
393 
394 	FRAME_COUNT = 0;
395 
396 	bool br = Menu2_Render();
397 
398 	if (br)
399 	{
400 		return br;
401 	}
402 
403 	if (ARXmenu.currentmode == AMCM_OFF)
404 	{
405 		return false;
406 	}
407 
408 	if (GInput->getMouseButton(Mouse::Button_0))
409 	{
410 		EERIEMouseButton = 1;
411 		LastMouseClick = 1;
412 	}
413 	else if (GInput->getMouseButton(Mouse::Button_1))
414 	{
415 		EERIEMouseButton = 2;
416 		LastMouseClick = 2;
417 	}
418 	else
419 	{
420 		EERIEMouseButton = 0;
421 	}
422 
423 	GRenderer->BeginScene();
424 
425 	GRenderer->Clear(Renderer::ColorBuffer | Renderer::DepthBuffer);
426 
427 	FLYING_OVER = 0;
428 
429 	//-------------------------------------------------------------------------
430 
431 	if ((ARXmenu.currentmode == AMCM_NEWQUEST) && (ARXmenu.mda))
432 	{
433 		if (ITC.Get("questbook") == NULL)
434 		{
435 			ARX_Menu_Resources_Release(false);
436 			ARX_Menu_Resources_Create();
437 
438 			// TODO this is also in Interface.cpp
439 
440 			ITC.Set("playerbook", "graph/interface/book/character_sheet/char_sheet_book");
441 			ITC.Set("ic_casting", "graph/interface/book/character_sheet/buttons_carac/icone_casting");
442 			ITC.Set("ic_close_combat", "graph/interface/book/character_sheet/buttons_carac/icone_close_combat");
443 			ITC.Set("ic_constitution", "graph/interface/book/character_sheet/buttons_carac/icone_constit");
444 			ITC.Set("ic_defense", "graph/interface/book/character_sheet/buttons_carac/icone_defense");
445 			ITC.Set("ic_dexterity", "graph/interface/book/character_sheet/buttons_carac/icone_dext");
446 			ITC.Set("ic_etheral_link", "graph/interface/book/character_sheet/buttons_carac/icone_etheral_link");
447 			ITC.Set("ic_mind", "graph/interface/book/character_sheet/buttons_carac/icone_intel");
448 			ITC.Set("ic_intuition", "graph/interface/book/character_sheet/buttons_carac/icone_intuition");
449 			ITC.Set("ic_mecanism", "graph/interface/book/character_sheet/buttons_carac/icone_mecanism");
450 			ITC.Set("ic_object_knowledge", "graph/interface/book/character_sheet/buttons_carac/icone_obj_knowledge");
451 			ITC.Set("ic_projectile", "graph/interface/book/character_sheet/buttons_carac/icone_projectile");
452 			ITC.Set("ic_stealth", "graph/interface/book/character_sheet/buttons_carac/icone_stealth");
453 			ITC.Set("ic_strength", "graph/interface/book/character_sheet/buttons_carac/icone_strenght");
454 
455 			ITC.Set("questbook", "graph/interface/book/questbook");
456 			ITC.Set("ptexspellbook", "graph/interface/book/spellbook");
457 			ITC.Set("bookmark_char", "graph/interface/book/bookmark_char");
458 			ITC.Set("bookmark_magic", "graph/interface/book/bookmark_magic");
459 			ITC.Set("bookmark_map", "graph/interface/book/bookmark_map");
460 			ITC.Set("bookmark_quest", "graph/interface/book/bookmark_quest");
461 
462 			ITC.Set("accessible_1", "graph/interface/book/accessible/accessible_1");
463 			ITC.Set("accessible_2", "graph/interface/book/accessible/accessible_2");
464 			ITC.Set("accessible_3", "graph/interface/book/accessible/accessible_3");
465 			ITC.Set("accessible_4", "graph/interface/book/accessible/accessible_4");
466 			ITC.Set("accessible_5", "graph/interface/book/accessible/accessible_5");
467 			ITC.Set("accessible_6", "graph/interface/book/accessible/accessible_6");
468 			ITC.Set("accessible_7", "graph/interface/book/accessible/accessible_7");
469 			ITC.Set("accessible_8", "graph/interface/book/accessible/accessible_8");
470 			ITC.Set("accessible_9", "graph/interface/book/accessible/accessible_9");
471 			ITC.Set("accessible_10", "graph/interface/book/accessible/accessible_10");
472 			ITC.Set("current_1", "graph/interface/book/current_page/current_1");
473 			ITC.Set("current_2", "graph/interface/book/current_page/current_2");
474 			ITC.Set("current_3", "graph/interface/book/current_page/current_3");
475 			ITC.Set("current_4", "graph/interface/book/current_page/current_4");
476 			ITC.Set("current_5", "graph/interface/book/current_page/current_5");
477 			ITC.Set("current_6", "graph/interface/book/current_page/current_6");
478 			ITC.Set("current_7", "graph/interface/book/current_page/current_7");
479 			ITC.Set("current_8", "graph/interface/book/current_page/current_8");
480 			ITC.Set("current_9", "graph/interface/book/current_page/current_9");
481 			ITC.Set("current_10", "graph/interface/book/current_page/current_10");
482 
483 			ITC.Set("ptexcursorredist", "graph/interface/cursors/add_points");
484 
485 			ITC.Level = getLocalised("system_charsheet_player_lvl");
486 			ITC.Xp = getLocalised("system_charsheet_player_xp");
487 
488 			ANIM_Set(&player.useanim, herowaitbook);
489 
490 			player.useanim.flags |= EA_LOOP;
491 
492 			ARXOldTimeMenu = ARXTimeMenu = arxtime.get_updated();
493 			ARXDiffTimeMenu = 0;
494 		}
495 
496 		GRenderer->SetRenderState(Renderer::Fog, false);
497 		GRenderer->SetRenderState(Renderer::AlphaBlending, false);
498 
499 		if (ARXmenu.mda->BookBackground != NULL)
500 		{
501 			GRenderer->SetRenderState(Renderer::AlphaBlending, false);
502 			GRenderer->SetRenderState(Renderer::Fog, false);
503 			GRenderer->SetRenderState(Renderer::DepthWrite, false);
504 			GRenderer->SetRenderState(Renderer::DepthTest, false);
505 
506 			EERIEDrawBitmap2(0, 0, static_cast<float>(DANAESIZX), static_cast<float>(DANAESIZY), 0.9f, ARXmenu.mda->BookBackground, Color::white);
507 		}
508 
509 		BOOKZOOM = 1;
510 
511 		ARX_INTERFACE_ManageOpenedBook();
512 
513 
514 		if (ARXmenu.mda)
515 		{
516 			long DONE = 0;
517 
518 			if ((player.Skill_Redistribute == 0) && (player.Attribute_Redistribute == 0))
519 				DONE = 1;
520 
521 			float ox, oy;
522 			ox = Xratio;
523 			oy = Yratio;
524 			LASTBOOKBUTTON = BOOKBUTTON;
525 			BOOKBUTTON = EERIEMouseButton;
526 			Xratio = ox;
527 			Yratio = oy;
528 
529 			if (!ARXmenu.mda->flyover[FLYING_OVER].empty() ) //=ARXmenu.mda->flyover[FLYING_OVER];
530 			{
531 				if (FLYING_OVER != OLD_FLYING_OVER)
532 				{
533 
534 					float fRandom	= rnd() * 2;
535 
536 					int t = checked_range_cast<int>(fRandom);
537 
538 
539 					pTextManage->Clear();
540 					OLD_FLYING_OVER = FLYING_OVER;
541 					UNICODE_ARXDrawTextCenteredScroll(hFontInGame,
542 						(DANAESIZX * 0.5f),
543 						12,
544 						(DANAECENTERX) * 0.82f,
545 						ARXmenu.mda->flyover[FLYING_OVER],
546 						Color(232 + t, 204 + t, 143 + t),
547 						1000,
548 						0.01f,
549 						2);
550 				}
551 			}
552 			else
553 			{
554 				OLD_FLYING_OVER = -1;
555 			}
556 
557 			float fPosX = 0;
558 			float fPosY = 313 * Yratio + (DANAESIZY - 313 * Yratio) * 0.70f;
559 
560 			float fSizeX = 100 * Xratio;
561 			float fSizeY = 100 * Yratio;
562 
563 			Color color = Color::none;
564 
565 			//---------------------------------------------------------------------
566 			// Button QUICK GENERATION
567 			fPosX = (DANAESIZX - (513 * Xratio)) * 0.5f;
568 
569 			if (MouseInRect(fPosX, fPosY, fPosX + fSizeX + 50, fPosY + fSizeY))
570 			{
571 				SpecialCursor = CURSOR_INTERACTION_ON;
572 				FLYING_OVER = BUTTON_QUICK_GENERATION;
573 
574 				if (EERIEMouseButton & 1) ;
575 				else if ((!(EERIEMouseButton & 1)) && (LastMouseClick & 1))
576 				{
577 					QUICK_MOD++;
578 					int iSkin = player.skin;
579 					ARX_MENU_CLICKSOUND();
580 
581 					if (bQuickGenFirstClick)
582 					{
583 						ARX_PLAYER_MakeAverageHero();
584 						bQuickGenFirstClick = false;
585 					}
586 					else
587 					{
588 						ARX_PLAYER_QuickGeneration();
589 					}
590 
591 					player.skin = checked_range_cast<char>(iSkin);
592 				}
593 
594 				color = Color(255, 255, 255);
595 			}
596 			else
597 				color = Color(232, 204, 143);
598 
599 			pTextManage->AddText(hFontMenu, ARXmenu.mda->str_button_quickgen, static_cast<long>(fPosX), static_cast<long>(fPosY), color);
600 
601 			//---------------------------------------------------------------------
602 			// Button SKIN
603 			fPosX = DANAESIZX * 0.5f;
604 
605 			if (MouseInRect(fPosX, fPosY, fPosX + fSizeX, fPosY + fSizeY))
606 			{
607 				SpecialCursor = CURSOR_INTERACTION_ON;
608 				FLYING_OVER = BUTTON_SKIN;
609 
610 				if ((!(EERIEMouseButton & 1)) && (LastMouseClick & 1))
611 				{
612 					SKIN_MOD++;
613 					BOOKZOOM = 1;
614 					ARX_MENU_CLICKSOUND();
615 					player.skin++;
616 
617 					if (player.skin > 3)  player.skin = 0;
618 
619 					switch (player.skin)
620 					{
621 						case 0:
622 							ePlayerAngle.b = -25.f;
623 							break;
624 						case 1:
625 							ePlayerAngle.b = -10.f;
626 							break;
627 						case 2:
628 							ePlayerAngle.b = 20.f;
629 							break;
630 						case 3:
631 							ePlayerAngle.b = 35.f;
632 							break;
633 					}
634 
635 					ARX_PLAYER_Restore_Skin();
636 				}
637 
638 				color = Color(255, 255, 255);
639 			}
640 			else
641 				color = Color(232, 204, 143);
642 
643 			pTextManage->AddText(hFontMenu, ARXmenu.mda->str_button_skin, static_cast<long>(fPosX), static_cast<long>(fPosY), color);
644 
645 			//---------------------------------------------------------------------
646 			// Button DONE
647 			fPosX = DANAESIZX - (DANAESIZX - 513 * Xratio) * 0.5f - 40 * Xratio;
648 
649 			if (MouseInRect(fPosX, fPosY, fPosX + fSizeX, fPosY + fSizeY))
650 			{
651 				if (DONE) SpecialCursor = CURSOR_INTERACTION_ON;
652 
653 				FLYING_OVER = BUTTON_DONE;
654 
655 				if ((DONE) && (!(EERIEMouseButton & 1)) && (LastMouseClick & 1))
656 				{
657 					if ((SKIN_MOD == 8) && (QUICK_MOD == 10))
658 					{
659 						SKIN_MOD = -2;
660 					}
661 					else if (SKIN_MOD == -1)
662 					{
663 						ARX_PLAYER_MakeSpHero();
664 						player.skin = 4;
665 						ARX_PLAYER_Restore_Skin();
666 						SKIN_MOD = 0;
667 						SP_HEAD = 1;
668 					}
669 					else
670 					{
671 						if (SP_HEAD)
672 						{
673 							player.skin = 4;
674 							ARX_PLAYER_Restore_Skin();
675 							SP_HEAD = 0;
676 						}
677 
678 						ARX_MENU_CLICKSOUND();
679 
680 						bFadeInOut = true;		//fade out
681 						bFade = true;			//active le fade
682 						iFadeAction = AMCM_OFF;
683 					}
684 				}
685 				else
686 				{
687 					if (DONE)
688 						color = Color(255, 255, 255);
689 					else
690 						color = Color(192, 192, 192);
691 				}
692 
693 			}
694 			else
695 			{
696 				if (DONE)
697 					color = Color(232, 204, 143);
698 				else
699 					color = Color(192, 192, 192);
700 			}
701 
702 			if (SKIN_MOD < 0)
703 				color = Color(255, 0, 255);
704 
705 			pTextManage->AddText(hFontMenu, ARXmenu.mda->str_button_done, static_cast<long>(fPosX), static_cast<long>(fPosY), color);
706 		}
707 	}
708 
709 	DynLight[0].pos.x = 0.f + GInput->getMousePosAbs().x - (DANAESIZX >> 1);
710 	DynLight[0].pos.y = 0.f + GInput->getMousePosAbs().y - (DANAESIZY >> 1);
711 
712 	if (pTextManage)
713 	{
714 		pTextManage->Update(FrameDiff);
715 		pTextManage->Render();
716 	}
717 
718 	if (ARXmenu.currentmode != AMCM_CREDITS)
719 		ARX_INTERFACE_RenderCursor(1);
720 
721 	if (ARXmenu.currentmode == AMCM_NEWQUEST)
722 	{
723 		if (ProcessFadeInOut(bFadeInOut, 0.1f))
724 		{
725 			switch (iFadeAction)
726 			{
727 				case AMCM_OFF:
728 					arxtime.resume();
729 					ARX_MENU_NEW_QUEST_Clicked_QUIT();
730 					iFadeAction = -1;
731 					bFade = false;
732 					fFadeInOut = 0.f;
733 
734 					if (pTextManage)
735 						pTextManage->Clear();
736 
737 					break;
738 			}
739 		}
740 	}
741 
742 	GRenderer->EndScene();
743 	return true;
744 }
745