1 /*
2 Copyright (C) 2007, 2010 - Bit-Blot
3 
4 This file is part of Aquaria.
5 
6 Aquaria is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (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.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21 #include "../BBGE/DebugFont.h"
22 #include "../ExternalLibs/glpng.h"
23 #include "../BBGE/AfterEffect.h"
24 #include "../BBGE/ProfRender.h"
25 
26 #include "DSQ.h"
27 #include "States.h"
28 #include "Game.h"
29 #include "Logo.h"
30 #include "Avatar.h"
31 #include "Entity.h"
32 #include "Avatar.h"
33 #include "Shot.h"
34 #include "GridRender.h"
35 #include "AutoMap.h"
36 #include "PackRead.h"
37 
38 #include "RoundedRect.h"
39 #include "TTFFont.h"
40 #include "ModSelector.h"
41 #include "Network.h"
42 
43 
44 #ifdef BBGE_BUILD_OPENGL
45 	#include <sys/stat.h>
46 #endif
47 
48 #ifdef BBGE_BUILD_VFS
49 #include "ttvfs.h"
50 #endif
51 
52 #ifdef BBGE_BUILD_UNIX
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <unistd.h>
56 #include <dirent.h>
57 #include <fcntl.h>
58 
Linux_CopyTree(const char * src,const char * dst)59 static void Linux_CopyTree(const char *src, const char *dst)
60 {
61     //printf("Linux_CopyTree('%s', '%s')...\n", src, dst);
62 
63     struct stat statbuf;
64     if (stat(src, &statbuf) == -1)
65         return;
66 
67     if (S_ISDIR(statbuf.st_mode))
68     {
69         createDir(dst);  // don't care if this fails.
70         DIR *dirp = opendir(src);
71         if (dirp == NULL)
72             return;
73 
74         struct dirent *dent;
75         while ((dent = readdir(dirp)) != NULL)
76         {
77             if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0))
78                 continue;
79             const size_t srclen = strlen(src) + strlen(dent->d_name) + 2;
80             char *subsrc = new char[srclen];
81             snprintf(subsrc, srclen, "%s/%s", src, dent->d_name);
82             const size_t dstlen = strlen(dst) + strlen(dent->d_name) + 2;
83             char *subdst = new char[dstlen];
84             snprintf(subdst, dstlen, "%s/%s", dst, dent->d_name);
85             Linux_CopyTree(subsrc, subdst);
86             delete[] subdst;
87             delete[] subsrc;
88         }
89         closedir(dirp);
90     }
91 
92     else if (S_ISREG(statbuf.st_mode))
93     {
94         const int in = open(src, O_RDONLY);
95         if (in == -1)
96             return;
97 
98         // fail if it already exists. That's okay in this case.
99         const int out = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0600);
100         if (out == -1)
101         {
102             close(in);
103             return;
104         }
105 
106         const size_t buflen = 256 * 1024;
107         char *buf = new char[buflen];
108         bool failed = false;
109         ssize_t br = 0;
110         while ( (!failed) && ((br = read(in, buf, buflen)) > 0) )
111             failed = (write(out, buf, br) != br);
112 
113         if (br < 0)
114             failed = true;
115 
116         delete[] buf;
117 
118         if (close(out) < 0)
119             failed = true;
120 
121         close(in);
122 
123         if (failed)
124             unlink(dst);
125     }
126 
127     else
128     {
129         fprintf(stderr, "WARNING: we should have copied %s to %s, but it's not a dir or file! Skipped it.\n", src, dst);
130     }
131 }
132 #endif
133 
134 
135 const int saveSlotPageSize = 4;
136 int maxPages = 15;
137 #ifdef AQUARIA_BUILD_CONSOLE
138 const int MAX_CONSOLELINES	= 18;
139 #endif
140 
141 DSQ *dsq = 0;
142 
143 const bool isReleaseCandidate	= false;
144 const bool isFinalCandidate		= false;
145 const bool isGoldMaster			= true;
146 
147 int setInpGrab = -1;
148 
149 Vector savesz;
150 
151 /// WARNING: this is just to init, the actual value is set from user settings!
152 #define PARTICLE_AMOUNT_DEFAULT			2048	// 64 // 1024 // 2048
153 
154 #ifdef AQUARIA_DEMO
155 	#define APPNAME "Aquaria Demo"
156 #else
157 	#define APPNAME "Aquaria"
158 #endif
159 
DSQ(const std::string & fileSystem,const std::string & extraDataDir)160 DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir)
161 : Core(fileSystem, extraDataDir, LR_MAX, APPNAME, PARTICLE_AMOUNT_DEFAULT, "Aquaria")
162 {
163 	dsq = this;
164 
165 	cutscene_bg = 0;
166 	cutscene_text = 0;
167 	cutscene_text2 = 0;
168 
169 	doScreenTrans = false;
170 
171 	cutscenePaused = false;
172 	inCutscene = false;
173 	_canSkipCutscene = false;
174 	skippingCutscene = false;
175 
176 	almb = armb = 0;
177 	bar_left = bar_right = bar_up = bar_down = barFade_left = barFade_right = 0;
178 
179 	difficulty = DIFF_NORMAL;
180 
181 	/*
182 	if (exists("easy"))
183 		difficulty = DIFF_EASY;//DIFF_NORMAL;
184 	*/
185 
186 	watchQuitFlag = false;
187 	watchForQuit = false;
188 
189 	particleBank1 = "data/particles/";
190 	particleBank2 = "";
191 
192 	shotBank1 = "data/shots/";
193 	shotBank2 = "";
194 
195 	disableMiniMapOnNoInput = true;
196 	noEffectTimer = 0;
197 	saveSlotPageCount = 0;
198 	inModSelector = false;
199 	subtext = 0;
200 	subbox = 0;
201 	menuSelectDelay = 0;
202 	modSelectorScr = 0;
203 	blackout = 0;
204 	inputMode = INPUT_MOUSE;
205 	overlay = 0;
206 	recentSaveSlot = -1;
207 	arialFontData = 0;
208 
209 #ifdef BBGE_BUILD_ACHIEVEMENTS_INTERNAL
210 	achievement_text = 0;
211 	achievement_box = 0;
212 #endif
213 
214 #ifdef AQUARIA_BUILD_CONSOLE
215 	console = 0;
216 #endif
217 	cmDebug = 0;
218 	languagePack = "english";
219 	saveSlotMode = SSM_NONE;
220 	afterEffectManagerLayer = LR_AFTER_EFFECTS; // LR_AFTER_EFFECTS
221 	renderObjectLayers.resize(LR_MAX);
222 
223 	entities.resize(64, 0);
224 
225 	//Emitter::particleLayer = LR_PARTICLES;
226 	sortEnabled = false;
227 	shakeCameraTimer = shakeCameraMag = 0;
228 	avgFPS.resize(dsq->user.video.fpsSmoothing);
229 
230 	cursor = cursorGlow = 0;
231 
232 	for (int i = 0; i < 16; i++)
233 		firstElementOnLayer[i] = 0;
234 
235 	//stream = 0;
236 }
237 
~DSQ()238 DSQ::~DSQ()
239 {
240 	dsq = 0;
241 }
242 
onAltTab()243 void DSQ::onAltTab()
244 {
245 	if (getAltState())
246 	{
247 		if (!core->isNested())
248 		{
249 			if (_fullscreen)
250 			{
251 				core->toggleScreenMode(false);
252 			}
253 		}
254 	}
255 }
256 
257 // actually toggle
toggleFullscreen()258 void DSQ::toggleFullscreen()
259 {
260 	//if (!core->isNested() && !core->sound->isPlayingVoice()) {
261 	core->toggleScreenMode(!_fullscreen);
262 	user.video.full = _fullscreen;
263 	//}
264 }
265 
266 // for handling the input, not the actual switch functionality
onSwitchScreenMode()267 void DSQ::onSwitchScreenMode()
268 {
269 	//if (!core->isNested() && !core->sound->isPlayingVoice())
270 	{
271 
272 #if defined(BBGE_BUILD_WINDOWS) || defined(BBGE_BUILD_UNIX)
273 		if (getAltState()) {
274 			toggleFullscreen();
275 		}
276 #endif
277 	}
278 }
279 
forceInputGrabOff()280 void DSQ::forceInputGrabOff()
281 {
282 	toggleInputGrabPlat(false);
283 	setInpGrab = 0;
284 #ifdef BBGE_BUILD_SDL
285 	SDL_ShowCursor(SDL_DISABLE);
286 #endif
287 }
288 
rumble(float leftMotor,float rightMotor,float time)289 void DSQ::rumble(float leftMotor, float rightMotor, float time)
290 {
291 	if (this->inputMode == INPUT_JOYSTICK)
292 		core->joystick.rumble(leftMotor, rightMotor, time);
293 }
294 
newGame()295 void DSQ::newGame()
296 {
297 	dsq->game->resetFromTitle();
298 	dsq->initScene = "NaijaCave";
299 	dsq->game->transitionToScene(dsq->initScene);
300 }
301 
loadElementEffects()302 void DSQ::loadElementEffects()
303 {
304 	bool found = false;
305 	std::string fn;
306 	if (dsq->mod.isActive())
307 	{
308 		fn = dsq->mod.getPath() + "elementeffects.txt";
309 		if(exists(fn))
310 			found = true;
311 	}
312 	if(!found)
313 		fn = "data/elementeffects.txt";
314 
315 	InStream inFile(fn.c_str());
316 	elementEffects.clear();
317 	std::string line;
318 	while (std::getline(inFile, line))
319 	{
320 		debugLog("Line: " + line);
321 		std::istringstream is(line);
322 		ElementEffect e;
323 		int efxType = EFX_NONE;
324 		int idx;
325 		std::string type;
326 		is >> idx >> type;
327 		if (type == "EFX_SEGS")
328 		{
329 			efxType = EFX_SEGS;
330 			is >> e.segsx >> e.segsy >> e.segs_dgox >> e.segs_dgoy >> e.segs_dgmx >> e.segs_dgmy >> e.segs_dgtm >> e.segs_dgo;
331 		}
332 		else if (type == "EFX_WAVY")
333 		{
334 			debugLog("loading wavy");
335 			efxType = EFX_WAVY;
336 			is >> e.segsy >> e.wavy_radius >> e.wavy_flip;
337 			// >> e.wavy_min >> e.wavy_max >> e.wavy_flip;
338 		}
339 		else if (type == "EFX_ALPHA")
340 		{
341 			efxType = EFX_ALPHA;
342 			float to_x, time, loop, pingPong, ease;
343 			is >> e.blendType >> e.alpha.x >> to_x >> time >> loop >> pingPong >> ease;
344 			e.alpha.interpolateTo(to_x, time, loop, pingPong, ease);
345 		}
346 		e.type = efxType;
347 		elementEffects.push_back(e);
348 	}
349 	inFile.close();
350 }
351 
getElementEffectByIndex(int e)352 ElementEffect DSQ::getElementEffectByIndex(int e)
353 {
354 	if (e < elementEffects.size() && e >= 0)
355 	{
356 		return elementEffects[e];
357 	}
358 
359 	ElementEffect empty;
360 	empty.type = EFX_NONE;
361 
362 	return empty;
363 }
364 
centerMessage(const std::string & text,float y,int type)365 void DSQ::centerMessage(const std::string &text, float y, int type)
366 {
367 	Vector pos(400,y);
368 	float time = 2;
369 
370 	BitmapText *t = 0;
371 	if (type == 1)
372 		t = new BitmapText(&smallFontRed);
373 	else
374 		t = new BitmapText(&smallFont);
375 	t->position = pos;
376 	t->alpha.ensureData();
377 	t->alpha.data->path.addPathNode(1, 0);
378 	t->alpha.data->path.addPathNode(1, 0.8);
379 	t->alpha.data->path.addPathNode(0, 1);
380 	t->alpha.startPath(time);
381 	t->followCamera = 1;
382 	t->setLife(time + 0.5f);
383 	t->setDecayRate(1);
384 	t->setText(text);
385 	t->offset.interpolateTo(Vector(0, -40), 2, 0, 0, 1);
386 	getTopStateData()->addRenderObject(t, LR_OVERLAY);
387 }
388 
centerText(const std::string & text)389 void DSQ::centerText(const std::string &text)
390 {
391 	Vector pos(400,200);
392 	float time = 8;
393 
394 	BitmapText *s = new BitmapText(&font);
395 	s->color = Vector(0,0,0);
396 	s->position = pos;
397 	s->offset = Vector(1,1);
398 	s->setText(text);
399 	s->setLife(time + 0.5f);
400 	s->setDecayRate(1);
401 	s->followCamera = 1;
402 	s->alpha.ensureData();
403 	s->alpha.data->path.addPathNode(0, 0);
404 	s->alpha.data->path.addPathNode(1, 0.1);
405 	s->alpha.data->path.addPathNode(1, 0.8);
406 	s->alpha.data->path.addPathNode(0, 1);
407 	s->alpha.startPath(time);
408 	getTopStateData()->addRenderObject(s, LR_HUD);
409 
410 
411 	BitmapText *t = new BitmapText(&font);
412 
413 
414 	t->position =pos;
415 	t->alpha.ensureData();
416 	t->alpha.data->path.addPathNode(0, 0);
417 	t->alpha.data->path.addPathNode(1, 0.1);
418 	t->alpha.data->path.addPathNode(1, 0.8);
419 	t->alpha.data->path.addPathNode(0, 1);
420 	t->alpha.startPath(time);
421 	/*
422 	t->scale = Vector(0.7, 0.7);
423 	t->scale.interpolateTo(Vector(1, 1), 6);
424 	*/
425 	t->followCamera = 1;
426 	t->setLife(time + 0.5f);
427 	t->setDecayRate(1);
428 	//t->scrollText(text, 0.1);
429 	t->setText(text);
430 	getTopStateData()->addRenderObject(t, LR_HUD);
431 }
432 
destroyFonts()433 void DSQ::destroyFonts()
434 {
435 	/*
436 	if (font) { delete font; font = 0; }
437 	if (smallFont) { delete smallFont; smallFont = 0; }
438 	if (subsFont) { delete subsFont; subsFont = 0; }
439 	if (goldFont) { delete goldFont; goldFont = 0; }
440 	*/
441 	debugLog("destroyFonts...");
442 	font.destroy();
443 	smallFont.destroy();
444 	subsFont.destroy();
445 	goldFont.destroy();
446 	smallFontRed.destroy();
447 
448 	debugLog("ttf fonts...");
449 	fontArialBig.destroy();
450 	fontArialSmall.destroy();
451 	fontArialSmallest.destroy();
452 	delete[] arialFontData;
453 	arialFontData = 0;
454 
455 	debugLog("done destroyFonts");
456 }
457 
loadFonts()458 void DSQ::loadFonts()
459 {
460 	debugLog("loadFonts...");
461 
462 	destroyFonts();
463 
464 	std::string file = localisePath("data/font-small.glf");
465 
466 	font.load(file, 1, false);
467 	font.fontTopColor = Vector(0.9,0.9,1);
468 	font.fontBtmColor = Vector(0.5,0.8,1);
469 	font.overrideTexture = core->addTexture("font");
470 
471 	smallFont.load(file, 0.6, false);
472 	smallFont.fontTopColor = Vector(0.9,0.9,1);
473 	smallFont.fontBtmColor = Vector(0.5,0.8,1);
474 	smallFont.overrideTexture = core->addTexture("font");
475 
476 	smallFontRed.load(file, 0.6, false);
477 	smallFontRed.fontTopColor = Vector(1,0.9,0.9);
478 	smallFontRed.fontBtmColor = Vector(1,0.8,0.5);
479 	smallFontRed.overrideTexture = core->addTexture("font");
480 
481 	subsFont.load(file, 0.5, false);
482 	subsFont.fontTopColor = Vector(1,1,1);
483 	subsFont.fontBtmColor = Vector(0.5,0.8,1);
484 	subsFont.overrideTexture = core->addTexture("font");
485 
486 	goldFont.load(file, 1, false);
487 	goldFont.fontTopColor = Vector(1,0.9,0.5);
488 	goldFont.fontBtmColor = Vector(0.6,0.5,0.25);
489 	goldFont.overrideTexture = core->addTexture("font");
490 
491 
492 	file = localisePath("data/font.ttf");
493 
494 	debugLog("ttf...");
495 	arialFontData = (unsigned char *)readFile(file, &arialFontDataSize);
496 	if (arialFontData)
497 	{
498 		fontArialSmall   .create(arialFontData, arialFontDataSize, 12);
499 		fontArialBig     .create(arialFontData, arialFontDataSize, 18);
500 		fontArialSmallest.create(arialFontData, arialFontDataSize, 10);
501 	}
502 	debugLog("done loadFonts");
503 
504 	/*
505 	//gold
506 	smallFont.fontTopColor = Vector(1,0.9,0.5);
507 	smallFont.fontBtmColor = Vector(0.6,0.5,0.25);
508 	*/
509 
510 	//Texture::format = GL_LUMINANCE_ALPHA;
511 
512 	//Texture::format = 0;
513 }
514 
onReloadResources()515 void DSQ::onReloadResources()
516 {
517 	Core::onReloadResources();
518 
519 	loadFonts();
520 
521 	setTexturePointers();
522 }
523 
debugMenu()524 void DSQ::debugMenu()
525 {
526 	if (isDeveloperKeys() || (mod.isActive() && mod.isDebugMenu()))
527 	{
528 /*
529 #if defined(BBGE_BUILD_MACOSX)
530 		if (core->getCtrlState())
531 #elif defined(BBGE_BUILD_WINDOWS) || defined(BBGE_BUILD_UNIX)
532 */
533 		if (core->getShiftState())
534 //#endif
535 		{
536 			core->frameOutputMode = false;
537 			dsq->game->togglePause(true);
538 			std::string s = dsq->getUserInputString(dsq->continuity.stringBank.get(2012), "");
539 			stringToUpper(s);
540 
541 			/*
542 			char c=0;
543 			is >> str;
544 			*/
545 
546 			/*
547 			if (dsq->postProcessingFx.isEnabled(FXT_RADIALBLUR))
548 			{
549 			dsq->postProcessingFx.disable(FXT_RADIALBLUR);
550 			}
551 			else
552 			{
553 			dsq->postProcessingFx.enable(FXT_RADIALBLUR);
554 			dsq->postProcessingFx.radialBlurColor = Vector(1,1,1);
555 			dsq->postProcessingFx.intensity = 0.1;
556 			}
557 			*/
558 
559 
560 			if (!dsq->game->isSceneEditorActive())
561 				dsq->game->togglePause(false);
562 			if (!s.empty())
563 			{
564 				char c = s[0];
565 				int i = 0;
566 				if (c == '1')
567 				{
568 					v.load();
569 
570 					core->particleManager->loadParticleBank(particleBank1, particleBank2);
571 
572 					// important: kill all shots before reloading the shot bank
573 					// still might crash here
574 					Shot::killAllShots();
575 					Shot::loadShotBank(shotBank1, shotBank2);
576 					dsq->continuity.loadEatBank();
577 
578 					dsq->game->loadEntityTypeList();
579 					if (core->afterEffectManager)
580 					{
581 						core->afterEffectManager->loadShaders();
582 					}
583 					dsq->user.load();
584 					dsq->continuity.loadIngredientData();
585 				}
586 				else if (c == '2')
587 				{
588 					if (dsq->game && dsq->game->avatar)
589 					{
590 						dsq->game->avatar->heal(999);
591 					}
592 				}
593 				else if (c == '3')
594 				{
595 					dsq->continuity.reset();
596 				}
597 				else if (c == 'B')
598 				{
599 					dsq->unloadResources();
600 				}
601 				else if (c == 'A')
602 				{
603 					dsq->reloadResources();
604 				}
605 				else if (c == 'J')
606 				{
607 					std::istringstream is(s);
608 					std::string state;
609 					char read = ' ';
610 					is >> read >> state;
611 
612 					dsq->quitNestedMain();
613 					dsq->enqueueJumpState(state);
614 				}
615 				else if (c == 'Q')
616 				{
617 					dsq->quitNestedMain();
618 				}
619 				/*
620 				else if (c == '4')
621 				{
622 				dsq->continuity.learnSong(SONG_FISHFORM);
623 				}
624 				else if (c == '5')
625 				{
626 				dsq->continuity.learnSong(SONG_NATUREFORM);
627 				}
628 				*/
629 				else if (c == '5')
630 				{
631 					/*
632 					if (dsq->game->avatar->isInvincible())
633 					dsq->game->avatar->setInvincible(false);
634 					else
635 					dsq->game->avatar->setInvincible(true);
636 					*/
637 					dsq->game->invinciblity = !dsq->game->invinciblity;
638 				}
639 				else if (c == '6')
640 				{
641 					while (core->getKeyState(KEY_RETURN))
642 						core->main(0.1);
643 					dsq->setStory();
644 				}
645 				else if (c == '8')
646 				{
647 					for (i = 0; i <= SONG_MAX; i++)
648 						dsq->continuity.learnSong(i);
649 				}
650 				else if (c == '9')
651 				{
652 					for (i = 0; i <= SONG_MAX; i++)
653 						dsq->continuity.learnSong(i);
654 					for (i = 0; i < FORMUPGRADE_MAX; i++)
655 					{
656 						dsq->continuity.learnFormUpgrade((FormUpgradeType)i);
657 					}
658 				}
659 				else if (c == '0')
660 				{
661 					dsq->continuity.learnSong(SONG_SHIELDAURA);
662 					dsq->continuity.learnSong(SONG_ENERGYFORM);
663 					dsq->continuity.learnSong(SONG_BIND);
664 				}
665 				else if (c == 'S')
666 				{
667 					std::istringstream is(s);
668 					int num = 0;
669 					char read=' ';
670 					is >> read >> num;
671 					dsq->continuity.learnSong(num);
672 
673 					/*
674 					std::ostringstream os;
675 					os << "debug: Learned Song: " << num << " from s: " << s;
676 					debugLog(os.str());
677 					*/
678 				}
679 				else if (c == 'F')
680 				{
681 					std::istringstream is(s);
682 					char read = ' ';
683 					std::string entityName;
684 					is >> read >> entityName;
685 					Entity *e = dsq->getEntityByNameNoCase(entityName);
686 					if (e)
687 					{
688 						dsq->cameraPos = game->getCameraPositionFor(e->position);
689 					}
690 				}
691 				else if (c == 'C')
692 				{
693 					std::istringstream is(s);
694 					std::string nm;
695 					char read=' ';
696 					is >> read >> nm;
697 					dsq->continuity.setCostume(nm);
698 				}
699 				else if (c == 'R')
700 				{
701 					dsq->demo.toggleRecord(true);
702 				}
703 				else if (c == 'P')
704 				{
705 					dsq->demo.togglePlayback(true);
706 				}
707 				else if (c == 'T')
708 				{
709 					if (dsq->demo.frames.size()> 0)
710 					{
711 						dsq->game->avatar->position = dsq->demo.frames[0].avatarPos;
712 						dsq->game->avatar->rotation.z = dsq->demo.frames[0].rot;
713 					}
714 				}
715 				else if (c == 'U')
716 				{
717 					dsq->demo.renderFramesToDisk();
718 					//dsq->demo.togglePlayback(true);
719 					//core->frameOutputMode = false;
720 				}
721 				else if (c == 'K')
722 				{
723 					dsq->demo.clearRecordedFrames();
724 				}
725 				else if (c == 'M')
726 				{
727 					dsq->game->autoMap->toggle(!dsq->game->autoMap->isOn());
728 				}
729 				else if (c == 'H')
730 				{
731 					std::ostringstream os;
732 					os << dsq->game->avatar->health;
733 					std::istringstream is(dsq->getUserInputString(dsq->continuity.stringBank.get(2013), os.str()));
734 					float h = 0;
735 					is >> h;
736 					dsq->game->avatar->health = h;
737 
738 				}
739 			}
740 
741 
742 			//dsq->game->togglePause(false);
743 		}
744 	}
745 }
746 
takeScreenshotKey()747 void DSQ::takeScreenshotKey()
748 {
749 	if (core->getCtrlState() && core->getAltState())
750 		takeScreenshot();
751 }
752 
753 Quad *loading=0;
754 
755 float loadingProgress = 0;
756 static const float loadingProgressTable[] = {
757 	#define LOAD_INITIAL	0  // Initial display (just so it's not empty)
758 	#define LOAD_PARTICLES	1  // After loading particles and shots
759 	#define LOAD_SOUNDCACHE	2  // After loading the sound cache
760 	#define LOAD_FONTS		3  // After loading fonts
761 	#define LOAD_GRAPHICS1	4  // After creating graphics resources
762 	#define LOAD_GRAPHICS2	5  // After creating more graphics resources
763 	#define LOAD_TEXTURES	6  // After loading textures to be precached
764 	#define LOAD_FINISHED	7  // All done!
765 	0.01, 0.07, 0.20, 0.23, 0.24, 0.25, 0.89, 1.00,
766 };
767 
loadBit(int index,float perc=1)768 void loadBit(int index, float perc = 1)
769 {
770 	const float previous = index==0 ? 0 : loadingProgressTable[index-1];
771 	const float next = loadingProgressTable[index];
772 	loadingProgress = MIN(1, previous + ((next - previous) * MIN(1, perc)));
773 
774 	loading->setWidthHeight(loadingProgress*600, 23);
775 
776 	core->render();
777 	core->showBuffer();
778 }
779 
780 unsigned int soundsLoaded = 0;
781 const unsigned int soundsExpected = 195;
loadBitForSoundCache()782 void loadBitForSoundCache()
783 {
784 	if (soundsLoaded > 0 && soundsLoaded < soundsExpected)
785 	{
786 		// Only update every 4 sounds so we don't waste too much
787 		// time waiting for vsync.
788 		if (soundsLoaded % 4 == 0)
789 		{
790 			loadBit(LOAD_SOUNDCACHE,
791 					(float)soundsLoaded / soundsExpected);
792 		}
793 	}
794 	soundsLoaded++;
795 }
796 
797 unsigned int texturesLoaded = 0;
798 const unsigned int texturesExpected = 652;
loadBitForTexPrecache()799 void loadBitForTexPrecache()
800 {
801 	if (texturesLoaded > 0 && texturesLoaded < texturesExpected)
802 	{
803 		if (texturesLoaded % 16 == 0)
804 		{
805 			loadBit(LOAD_TEXTURES,
806 					(float)texturesLoaded / texturesExpected);
807 		}
808 	}
809 	texturesLoaded++;
810 }
811 
812 
setVersionLabelText()813 void DSQ::setVersionLabelText()
814 {
815 #ifdef AQUARIA_OVERRIDE_VERSION_STRING
816 	std::string overrideText = AQUARIA_OVERRIDE_VERSION_STRING;
817 	if(user.system.allowDangerousScriptFunctions)
818 		overrideText += continuity.stringBank.get(2050);
819 	versionLabel->setText(overrideText);
820 	return;
821 #endif
822 
823 	std::ostringstream os;
824 	os << "Aquaria";
825 
826 #ifdef AQUARIA_DEMO
827 	os << " Demo";
828 #endif
829 
830 	os << " v" << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION;
831 
832 	if (!isFinalCandidate && !isGoldMaster && VERSION_BETA)
833 	{
834 		os << "b" << VERSION_BETA;
835 	}
836 
837 	if (isFinalCandidate)
838 	{
839 		os << "fc" << VERSION_FC;
840 	}
841 	else if (isReleaseCandidate)
842 	{
843 		os << "RC";
844 	}
845 	else if (isGoldMaster)
846 	{
847 		//os << "gm" << VERSION_GM;
848 	}
849 
850 	#ifdef AQUARIA_CUSTOM_BUILD_ID
851 	os << AQUARIA_CUSTOM_BUILD_ID;
852 	#endif
853 
854 	if(user.system.allowDangerousScriptFunctions)
855 		os << continuity.stringBank.get(2050);
856 
857 	versionLabel->setText(os.str());
858 }
859 
860 #ifdef BBGE_BUILD_SDL
sdlVideoModeOK(const int w,const int h,const int bpp)861 static bool sdlVideoModeOK(const int w, const int h, const int bpp)
862 {
863 #ifdef BBGE_BUILD_SDL2
864 	SDL_DisplayMode mode;
865 	const int modecount = SDL_GetNumDisplayModes(0);
866 	for (int i = 0; i < modecount; i++) {
867 		SDL_GetDisplayMode(0, i, &mode);
868         if (!mode.w || !mode.h || (w >= mode.w && h >= mode.h)) {
869 			return true;
870         }
871     }
872     return false;
873 #else
874 	return SDL_VideoModeOK(w, h, bpp, SDL_OPENGL | SDL_FULLSCREEN);
875 #endif
876 }
877 #endif
878 
init()879 void DSQ::init()
880 {
881 	core->settings.runInBackground = true;
882 
883 	weird = 0;
884 
885 #ifdef BBGE_BUILD_WINDOWS
886 	/*
887 	const std::string welcomeMessage = \
888 "Thank you for reviewing Aquaria!\n\
889 This build is not yet final, and as such there are a couple things lacking. They include:\n\
890   * documentation (not 100% complete)\n\
891   * mod editing (some known issues)\n\
892   * gamepad support/config (some known issues)\n\
893 \nFor the best experience, we recommend playing using the mouse or mouse and keyboard.\n\
894 			Have fun!";
895 
896 	if (!welcomeMessage.empty())
897 	{
898 		MessageBox(core->hWnd, welcomeMessage.c_str(), "Welcome to Aquaria", MB_OK);
899 	}
900 	*/
901 #endif
902 
903 	disableMiniMapOnNoInput = true;
904 	fpsText = 0;
905 	cmDebug = 0;
906 
907 	routeShoulder = true;
908 	debugLog("DSQ init");
909 
910 	useFrameBuffer = false;
911 	gameSpeed = 1;
912 
913 	// steam gets inited in here
914 	Core::init();
915 
916 	continuity.stringBank.load();
917 
918 	vars = &v;
919 	v.load();
920 
921 	// steam callbacks are inited here
922 	continuity.init();
923 
924 	// do copy stuff
925 #ifdef BBGE_BUILD_UNIX
926 	std::string fn;
927 	fn = getPreferencesFolder() + "/" + userSettingsFilename;
928 	if (!exists(fn))
929 		Linux_CopyTree(core->adjustFilenameCase(userSettingsFilename).c_str(), core->adjustFilenameCase(fn).c_str());
930 
931 	fn = getUserDataFolder() + "/_mods";
932 	if (!exists(fn))
933 		Linux_CopyTree(core->adjustFilenameCase("_mods").c_str(), core->adjustFilenameCase(fn).c_str());
934 #endif
935 
936 	createDir(getUserDataFolder());
937 	createDir(getUserDataFolder() + "/save");
938 	createDir(getUserDataFolder() + "/_mods");
939 	createDir(getUserDataFolder() + "/screenshots");
940 
941 	addStateInstance(game = new Game);
942 	addStateInstance(new GameOver);
943 #ifdef AQUARIA_BUILD_SCENEEDITOR
944 	addStateInstance(new AnimationEditor);
945 #endif
946 	addStateInstance(new Intro2);
947 	addStateInstance(new BitBlotLogo);
948 #ifdef AQUARIA_BUILD_SCENEEDITOR
949 	addStateInstance(new ParticleEditor);
950 #endif
951 	addStateInstance(new Credits);
952 	addStateInstance(new Intro);
953 	addStateInstance(new Nag);
954 
955 	//addStateInstance(new Logo);
956 	//addStateInstance(new SCLogo);
957 	//addStateInstance(new IntroText);
958 	//addStateInstance(new Intro);
959 
960 	//packReadInfo("mus.dat");
961 
962 	this->setBaseTextureDirectory("gfx/");
963 	//sound->setMusicVolume(0);
964 
965 //	PHYSFS_addToSearchPath("gfx",1);
966 //	PHYSFS_addToSearchPath("gfx.zpk",0 );
967 
968 	bool mipmapsEnabled=true;
969 	bool fullscreen = true;
970 	int joystickMode = 0;
971 	int dsq_filter = 0;
972 	voiceOversEnabled = true;
973 
974 
975 	//core->messageBox("info", "loading user settings");
976 	user.load(false);
977 
978 	particleManager->setSize(user.video.numParticles);
979 
980 	fullscreen = user.video.full;
981 
982 	float asp = float(user.video.resx)/float(user.video.resy);
983 
984 	if(asp < 1.0f)
985 	{
986 		std::ostringstream os;
987 		os << "Aspect ratio for resolution [" << user.video.resx << ", " << user.video.resy << "] not supported.";
988 		exit_error(os.str());
989 	}
990 
991 	setFilter(dsq_filter);
992 
993 	useFrameBuffer = user.video.fbuffer;
994 
995 	if (isDeveloperKeys())
996 	{
997 		maxPages = 600/saveSlotPageSize;
998 	}
999 
1000 	if (mipmapsEnabled)
1001 		debugLog("Mipmaps Enabled");
1002 	else
1003 		debugLog("Mipmaps Disabled");
1004 
1005 	Texture::useMipMaps = mipmapsEnabled;
1006 
1007 	if (isDeveloperKeys())
1008 		debugLog("DeveloperKeys Enabled");
1009 	else
1010 		debugLog("DeveloperKeys Disabled");
1011 
1012 	if (voiceOversEnabled)
1013 		debugLog("VoiceOvers Enabled");
1014 	else
1015 		debugLog("VoiceOvers Disabled");
1016 
1017 
1018 #ifdef _DEBUG
1019 	if (!createWindow(800, 600, user.video.bits, false, "Aquaria"))
1020 #else
1021 	if (!createWindow(user.video.resx, user.video.resy, user.video.bits, user.video.full, "Aquaria"))
1022 #endif
1023 	{
1024 		exit_error("Failed to create window");
1025 		return;
1026 	}
1027 
1028 	/*
1029 	debugLog("Setting Music Volume...");
1030 		if (musicVolume != 0)
1031 		{
1032 			musicVolume = 0.9;
1033 		}
1034 		sound->setMusicVolume(musicVolume);
1035 	debugLog("OK");
1036 	*/
1037 
1038 #ifdef BBGE_BUILD_SDL
1039 	SDL_Init(SDL_INIT_VIDEO);
1040 	if (fullscreen && !sdlVideoModeOK(user.video.resx, user.video.resy, user.video.bits))
1041 	{
1042 		// maybe we can force a sane resolution if SetVideoMode is going to fail...
1043 		user.video.resx = 800;
1044 		user.video.resy = 600;
1045 		if (!sdlVideoModeOK(user.video.resx, user.video.resy, user.video.bits))
1046 			fullscreen = false;  // last chance.
1047 	}
1048 #endif
1049 
1050 	debugLog("Init Graphics Library...");
1051 		initGraphicsLibrary(user.video.resx, user.video.resy, fullscreen, user.video.vsync, user.video.bits);
1052 		core->enable2DWide(user.video.resx, user.video.resy);
1053 		core->initFrameBuffer();
1054 	debugLog("OK");
1055 
1056 	setInputGrab(0);
1057 	dsq->forceInputGrabOff();
1058 
1059 	debugLog("Init Sound Library...");
1060 		initSoundLibrary(user.audio.deviceName);
1061 		debugLog("Set Voice Fader");
1062 		sound->setVoiceFader(0.5);
1063 		sound->event_playVoice.set(MakeFunctionEvent(DSQ, onPlayVoice));
1064 		sound->event_stopVoice.set(MakeFunctionEvent(DSQ, onStopVoice));
1065 		//sound->reverbKeyword = "naija_";
1066 	debugLog("OK");
1067 
1068 	debugLog("Init Input Library...");
1069 		initInputLibrary();
1070 	debugLog("OK");
1071 
1072 
1073 	joystickMode = user.control.joystickEnabled;
1074 	if (joystickMode)
1075 	{
1076 		debugLog("Init Joystick Library...");
1077 			initJoystickLibrary();
1078 			/*
1079 			if (joystickEnabled)
1080 				joystickOverrideMouse = true;
1081 			*/
1082 		debugLog("OK");
1083 	}
1084 
1085 	user.apply();
1086 
1087 	applyPatches();
1088 
1089 	loading = new Quad("loading/juice", Vector(400,300));
1090 	loading->alpha = 1.0;
1091 	loading->followCamera = 1;
1092 	loading->setWidthHeight(0,0);
1093 	addRenderObject(loading, LR_HUD);
1094 
1095 	Vector loadShift(2, 0);
1096 
1097 
1098 	Vector sz(800.0f/1024.0f, 600.0f/768.0f);
1099 
1100 
1101 
1102 	Quad *tube = new Quad("loading/tube", Vector(400, 300));
1103 	tube->followCamera = 1;
1104 	tube->scale = sz;
1105 	addRenderObject(tube, LR_HUD);
1106 
1107 	Quad *label = new Quad("loading/label", Vector(400, 300));
1108 	label->followCamera = 1;
1109 	label->scale = sz;
1110 	addRenderObject(label, LR_HUD);
1111 
1112 	int sideOut = 300, sideDown = 8;
1113 
1114 	Quad *sidel = new Quad("loading/side", Vector(400-sideOut, 300+sideDown));
1115 	sidel->followCamera = 1;
1116 	sidel->scale = sz;
1117 	addRenderObject(sidel, LR_HUD);
1118 
1119 	Quad *sider = new Quad("loading/side", Vector(400+sideOut, 300+sideDown));
1120 	sider->flipHorizontal();
1121 	sider->followCamera = 1;
1122 	sider->scale = sz;
1123 	addRenderObject(sider, LR_HUD);
1124 	/*
1125 	DebugFont *loadingFont = new DebugFont(6, "LOADING");
1126 	loadingFont->alpha = 1;
1127 	loadingFont->setAlign(DebugFont::ALIGN_CENTER);
1128 	loadingFont->position = Vector(400,300) + loadShift;
1129 	loadingFont->followCamera = 1;
1130 	addRenderObject(loadingFont, LR_HUD);
1131 
1132 	Vector shift(-12, 0);
1133 
1134 	DebugFont *lbit1 = new DebugFont(32, "[");
1135 	//lbit1->setAlign(DebugFont::ALIGN_CENTER);
1136 	lbit1->position = Vector(100,300) + shift;
1137 	lbit1->followCamera = 1;
1138 	addRenderObject(lbit1, LR_HUD);
1139 
1140 	DebugFont *lbit2 = new DebugFont(32, "]");
1141 	//lbit2->setAlign(DebugFont::ALIGN_CENTER);
1142 	lbit2->position = Vector(700,300) + shift;
1143 	lbit2->followCamera = 1;
1144 	addRenderObject(lbit2, LR_HUD);
1145 	*/
1146 
1147 	core->render();
1148 	core->showBuffer();
1149 
1150 
1151 
1152 	loadBit(LOAD_INITIAL);
1153 
1154 	debugLog("Loading Particle Bank...");
1155 	{
1156 		core->particleManager->loadParticleBank(particleBank1, particleBank2);
1157 		Shot::loadShotBank(shotBank1, shotBank2);
1158 	}
1159 	debugLog("OK");
1160 
1161 	loadBit(LOAD_PARTICLES);
1162 
1163 
1164 
1165 	debugLog("Loading Sound Cache...");
1166 		sound->loadSoundCache("sfx/cache/", ".ogg", loadBitForSoundCache);
1167 	debugLog("OK");
1168 
1169 	loadBit(LOAD_SOUNDCACHE);
1170 
1171 
1172 	debugLog("Init Script Interface...");
1173 		scriptInterface.init();
1174 	debugLog("OK");
1175 
1176 	loadFonts();
1177 
1178 	loadBit(LOAD_FONTS);
1179 
1180 	dsq->continuity.stringBank.load();
1181 
1182 	setTexturePointers();
1183 
1184 	cursor = new Quad;
1185 	{
1186 		cursor->alphaMod = 0.5;
1187 		cursor->toggleCull(false);
1188 		cursor->followCamera = 1;
1189 		cursor->setWidthHeight(24, 24);
1190 		cursor->alpha = 0;
1191 	}
1192 	addRenderObject (cursor, LR_CURSOR);
1193 
1194 	user.video.darkbuffersize = MAX(user.video.darkbuffersize,128);
1195 
1196 	dsq->darkLayer.setLayers(LR_ELEMENTS13, LR_AFTER_EFFECTS);
1197 	debugLog("dark layer init");
1198 	dsq->darkLayer.init(user.video.darkbuffersize, user.video.darkfbuffer);
1199 	debugLog("dark layer togle...");
1200 	dsq->darkLayer.toggle(0);
1201 	debugLog("done");
1202 
1203 	debugLog("post FX init");
1204 	dsq->postProcessingFx.init();
1205 	debugLog("done");
1206 
1207 
1208 #ifdef AQUARIA_BUILD_CONSOLE
1209 	debugLog("Creating console");
1210 	console = new DebugFont;
1211 	//(&dsq->smallFont);
1212 	{
1213 		console->position = Vector(10 - virtualOffX,400);
1214 		console->followCamera = 1;
1215 		console->alpha = 0;
1216 		//console->setAlign(ALIGN_LEFT);
1217 		//console->setWidth(12);
1218 		//console->setFontSize(12);
1219 		console->setFontSize(6);
1220 	}
1221 	addRenderObject(console, LR_DEBUG_TEXT);
1222 #else
1223 	debugLog("NOT creating console (disabled in this build)");
1224 #endif
1225 
1226 	debugLog("1");
1227 
1228 	if (isDeveloperKeys())
1229 	{
1230 		//cmDebug = new BitmapText(&dsq->font);
1231 		cmDebug = new DebugFont();
1232 		{
1233 			//cmDebug->position = Vector(450,250);
1234 			//cmDebug->position = Vector(500,350);
1235 			cmDebug->position = Vector(20 - virtualOffX,50);
1236 			cmDebug->followCamera = 1;
1237 			cmDebug->alpha = 0;
1238 			//cmDebug->setAlign(ALIGN_LEFT);
1239 			//cmDebug->setWidth(12);
1240 			//cmDebug->setFontSize(18);
1241 			cmDebug->setFontSize(6);
1242 		}
1243 		addRenderObject(cmDebug, LR_DEBUG_TEXT);
1244 	}
1245 
1246 	debugLog("2");
1247 
1248 	versionLabel = new BitmapText(&smallFont);
1249 	{
1250 	setVersionLabelText();
1251 	//versionLabel->position = Vector(10 - core->getVirtualOffX(), 575);
1252 	versionLabel->followCamera = 1;
1253 	versionLabel->setAlign(ALIGN_LEFT);
1254 	versionLabel->scale = Vector(0.7, 0.7);
1255 	versionLabel->alphaMod = 0.75;
1256 	versionLabel->alpha = 0;
1257 	}
1258 	addRenderObject(versionLabel, LR_REGISTER_TEXT);
1259 
1260 
1261 	subbox = new Quad();
1262 	subbox->position = Vector(400,580);
1263 	subbox->alpha = 0;
1264 	subbox->alphaMod = 0.7;
1265 	subbox->followCamera = 1;
1266 	subbox->autoWidth = AUTO_VIRTUALWIDTH;
1267 	subbox->setHeight(40);
1268 	subbox->color = 0;
1269 	addRenderObject(subbox, LR_SUBTITLES);
1270 
1271 	subtext = new BitmapText(&dsq->subsFont);
1272 	//subtext->position = Vector(400,570);
1273 	subtext->position = Vector(400,570);
1274 	subtext->followCamera = 1;
1275 	subtext->alpha = 0;
1276 	subtext->setFontSize(14);
1277 	subtext->setWidth(800);
1278 	subtext->setAlign(ALIGN_CENTER);
1279 	//subtext->setFontSize(12);
1280 	addRenderObject(subtext, LR_SUBTITLES);
1281 
1282 #ifdef BBGE_BUILD_ACHIEVEMENTS_INTERNAL
1283 	achievement_box = new Quad();
1284 	achievement_box->position = Vector(800,0);
1285 	achievement_box->alpha = 0;
1286 	achievement_box->alphaMod = 0.7;
1287 	achievement_box->followCamera = 1;
1288 	achievement_box->setWidthHeight(400, 87);
1289 	achievement_box->color = 0;
1290 	addRenderObject(achievement_box, LR_SUBTITLES);
1291 
1292 	achievement_text = new BitmapText(&dsq->subsFont);
1293 	achievement_text->position = Vector(603, 5);
1294 	achievement_text->followCamera = 1;
1295 	achievement_text->alpha = 0;
1296 	achievement_text->setFontSize(6);
1297 	achievement_text->setWidth(280);
1298 	achievement_text->setAlign(ALIGN_LEFT);
1299 	addRenderObject(achievement_text, LR_SUBTITLES);
1300 #endif
1301 
1302 	cutscene_bg = new Quad();
1303 	cutscene_bg->autoWidth = AUTO_VIRTUALWIDTH;
1304 	cutscene_bg->color = 0;
1305 	cutscene_bg->alphaMod = 0.75;
1306 	cutscene_bg->setWidthHeight(0, 80);
1307 	cutscene_bg->position = Vector(400,300);
1308 	cutscene_bg->alpha.x = 0;
1309 	cutscene_bg->followCamera = 1;
1310 	addRenderObject(cutscene_bg, LR_SUBTITLES);
1311 
1312 	cutscene_text = new BitmapText(&dsq->font);
1313 	cutscene_text->setText(dsq->continuity.stringBank.get(2004));
1314 	cutscene_text->position = Vector(400,300-16);
1315 	cutscene_text->alpha.x = 0;
1316 	cutscene_text->followCamera = 1;
1317 	addRenderObject(cutscene_text, LR_SUBTITLES);
1318 
1319 	cutscene_text2 = new BitmapText(&dsq->smallFont);
1320 	cutscene_text2->setText(dsq->continuity.stringBank.get(2005));
1321 	cutscene_text2->position = Vector(400,300+10);
1322 	cutscene_text2->alpha.x = 0;
1323 	cutscene_text2->followCamera = 1;
1324 	addRenderObject(cutscene_text2, LR_SUBTITLES);
1325 
1326 	debugLog("3");
1327 
1328 	loadBit(LOAD_GRAPHICS1);
1329 
1330 	debugLog("4");
1331 
1332 	cursorGlow = new Quad;
1333 	{
1334 		cursorGlow->setTexture("glow");
1335 		cursorGlow->setWidthHeight(48, 48);
1336 		cursorGlow->alpha = 0;
1337 		cursorGlow->setBlendType(RenderObject::BLEND_ADD);
1338 	}
1339 	cursor->addChild(cursorGlow, PM_NONE, RBP_OFF);
1340 	addRenderObject(cursorGlow, LR_CURSOR);
1341 
1342 	cursorBlinker = new Quad;
1343 	{
1344 		cursorBlinker->setTexture("cursor");
1345 		cursorBlinker->scale = Vector(1.5, 1.5);
1346 		cursorBlinker->scale.interpolateTo(Vector(2,2), 0.2, -1, 1, 1);
1347 		cursorBlinker->alpha = 0;
1348 		cursorBlinker->alphaMod = 0.5;
1349 	}
1350 	cursor->addChild(cursorBlinker, PM_NONE, RBP_OFF);
1351 	addRenderObject(cursorBlinker, LR_CURSOR);
1352 
1353 	debugLog("5");
1354 
1355 	recreateBlackBars();
1356 
1357 	debugLog("6");
1358 
1359 	overlay = new Quad;
1360 	{
1361 		overlay->position = Vector(400,300,3);
1362 		overlay->color = 0;
1363 		overlay->autoWidth = AUTO_VIRTUALWIDTH;
1364 		overlay->autoHeight = AUTO_VIRTUALHEIGHT;
1365 		overlay->alpha = 0;
1366 		overlay->followCamera = 1;
1367 	}
1368 	addRenderObject(overlay, LR_OVERLAY);
1369 
1370 	overlay2 = new Quad;
1371 	{
1372 		overlay2->position = Vector(400,300);
1373 		overlay2->color = 0;
1374 		overlay2->autoWidth = AUTO_VIRTUALWIDTH;
1375 		overlay2->autoHeight = AUTO_VIRTUALHEIGHT;
1376 		overlay2->alpha = 0;
1377 		overlay2->followCamera = 1;
1378 	}
1379 	addRenderObject(overlay2, LR_OVERLAY);
1380 
1381 	overlay3 = new Quad;
1382 	{
1383 		overlay3->position = Vector(400,300);
1384 		overlay3->color = 0;
1385 		overlay3->autoWidth = AUTO_VIRTUALWIDTH;
1386 		overlay3->autoHeight = AUTO_VIRTUALHEIGHT;
1387 		overlay3->alpha = 0;
1388 		overlay3->followCamera = 1;
1389 	}
1390 	addRenderObject(overlay3, LR_OVERLAY);
1391 
1392 	overlayRed = new Quad;
1393 	{
1394 		overlayRed->position = Vector(400,300);
1395 		overlayRed->color = Vector(1,0,0);
1396 		overlayRed->alphaMod = 0.5;
1397 		overlayRed->autoWidth = AUTO_VIRTUALWIDTH;
1398 		overlayRed->autoHeight = AUTO_VIRTUALHEIGHT;
1399 		overlayRed->alpha = 0;
1400 		overlayRed->followCamera = 1;
1401 	}
1402 	addRenderObject(overlayRed, LR_OVERLAY);
1403 
1404 	sceneColorOverlay = new Quad;
1405 	{
1406 		sceneColorOverlay->position = Vector(400,300);
1407 		sceneColorOverlay->color = Vector(1,1,1);
1408 		sceneColorOverlay->alpha = 1;
1409 		sceneColorOverlay->setBlendType(RenderObject::BLEND_MULT);
1410 		sceneColorOverlay->autoWidth = AUTO_VIRTUALWIDTH;
1411 		sceneColorOverlay->autoHeight = AUTO_VIRTUALHEIGHT;
1412 		sceneColorOverlay->followCamera = 1;
1413 	}
1414 	addRenderObject(sceneColorOverlay, LR_SCENE_COLOR);
1415 
1416 	tfader = new Quad;
1417 	{
1418 		tfader->position = Vector(400,300,3);
1419 		tfader->color = 0;
1420 		tfader->autoWidth = AUTO_VIRTUALWIDTH;
1421 		tfader->autoHeight = AUTO_VIRTUALHEIGHT;
1422 		tfader->alpha = 0;
1423 		tfader->followCamera = 1;
1424 	}
1425 	addRenderObject(tfader, LR_TRANSITION);
1426 
1427 	screenTransition = 0;
1428 
1429 	screenTransition = new AquariaScreenTransition();
1430 	{
1431 		screenTransition->position = Vector(400,300);
1432 	}
1433 	addRenderObject(screenTransition, LR_TRANSITION);
1434 
1435 	debugLog("8");
1436 
1437 	loadBit(LOAD_GRAPHICS2);
1438 
1439 	debugLog("9");
1440 
1441 
1442 	profRender = 0;
1443 #ifdef Prof_ENABLED
1444 	profRender = new ProfRender();
1445 	profRender->alpha = 0;
1446 	addRenderObject(profRender, LR_DEBUG_TEXT);
1447 #endif
1448 
1449 	//fpsText = new BitmapText(&dsq->smallFont);
1450 	fpsText = new DebugFont;
1451 	{
1452 		fpsText->color = Vector(1,1,1);
1453 		fpsText->setFontSize(6);
1454 		//fpsText->position = Vector(10,15+200);
1455 		fpsText->position = Vector(10 - virtualOffX,580);
1456 		fpsText->position.z = 5;
1457 		//fpsText->position += Vector(0,-200);
1458 		//fpsText->setAlign(ALIGN_LEFT);
1459 		fpsText->setText("FPS");
1460 		fpsText->alpha= 0;
1461 		//fpsText->followCamera = 1;
1462 	}
1463 	addRenderObject(fpsText, LR_DEBUG_TEXT);
1464 
1465 	precacher.precacheList("data/precache.txt", loadBitForTexPrecache);
1466 
1467 	setTexturePointers();
1468 
1469 	loadBit(LOAD_TEXTURES);
1470 
1471 	resetLayerPasses();
1472 
1473 	renderObjectLayerOrder[LR_BACKGROUND_ELEMENTS1] = LR_ELEMENTS1;
1474 	renderObjectLayerOrder[LR_BACKGROUND_ELEMENTS2] = LR_ELEMENTS2;
1475 	renderObjectLayerOrder[LR_BACKGROUND_ELEMENTS3] = LR_ELEMENTS3;
1476 
1477 	renderObjectLayerOrder[LR_FOREGROUND_ELEMENTS1] = LR_ELEMENTS8;
1478 	renderObjectLayerOrder[LR_FOREGROUND_ELEMENTS2] = LR_ELEMENTS9;
1479 
1480 	renderObjectLayerOrder[LR_BACKDROP_ELEMENTS1] = LR_ELEMENTS10;
1481 	renderObjectLayerOrder[LR_BACKDROP_ELEMENTS2] = LR_ELEMENTS11;
1482 	renderObjectLayerOrder[LR_BACKDROP_ELEMENTS3] = LR_ELEMENTS12;
1483 
1484 	renderObjectLayerOrder[LR_ENTITIES_MINUS4_PLACEHOLDER] = LR_ENTITIES_MINUS4;
1485 	renderObjectLayerOrder[LR_ENTITIES_MINUS3_PLACEHOLDER] = LR_ENTITIES_MINUS3;
1486 	renderObjectLayerOrder[LR_ENTITIES_MINUS2_PLACEHOLDER] = LR_ENTITIES_MINUS2;
1487 
1488 	renderObjectLayerOrder[LR_DARK_LAYER] = LR_ELEMENTS13;
1489 
1490 	renderObjectLayerOrder[LR_BACKDROP_ELEMENTS4] = LR_ELEMENTS14;
1491 	renderObjectLayerOrder[LR_BACKDROP_ELEMENTS5] = LR_ELEMENTS15;
1492 	renderObjectLayerOrder[LR_BACKDROP_ELEMENTS6] = LR_ELEMENTS16;
1493 
1494 	renderObjectLayerOrder[LR_ELEMENTS1] = -1;
1495 	renderObjectLayerOrder[LR_ELEMENTS2] = -1;
1496 	renderObjectLayerOrder[LR_ELEMENTS3] = -1;
1497 
1498 	renderObjectLayerOrder[LR_ELEMENTS8] = -1;
1499 	renderObjectLayerOrder[LR_ELEMENTS9] = -1;
1500 
1501 	renderObjectLayerOrder[LR_ELEMENTS10] = -1;
1502 	renderObjectLayerOrder[LR_ELEMENTS11] = -1;
1503 	renderObjectLayerOrder[LR_ELEMENTS12] = -1;
1504 
1505 	renderObjectLayerOrder[LR_ELEMENTS14] = -1;
1506 	renderObjectLayerOrder[LR_ELEMENTS15] = -1;
1507 	renderObjectLayerOrder[LR_ELEMENTS16] = -1;
1508 
1509 	renderObjectLayerOrder[LR_ELEMENTS13] = -1;
1510 
1511 	renderObjectLayerOrder[LR_ENTITIES_MINUS4] = -1;
1512 	renderObjectLayerOrder[LR_ENTITIES_MINUS3] = -1;
1513 	renderObjectLayerOrder[LR_ENTITIES_MINUS2] = -1;
1514 
1515 	/*if (!Entity::blurShader.isLoaded())
1516 	{
1517 		//Entity::blurShader.load("data/shaders/stan.vert", "data/shaders/hoblur.frag");
1518 	}*/
1519 
1520 	setMousePosition(core->center);
1521 
1522 	//dsq->continuity.reset();
1523 
1524 	loadBit(LOAD_FINISHED);
1525 
1526 	/*
1527 	sound->playSfx("defense", 0.5);
1528 	sound->playSfx("visionwakeup");
1529 	*/
1530 
1531 	// Don't do transitions for a faster start up in dev mode
1532 	if (!isDeveloperKeys())
1533 	{
1534 		float trans = 0.5;
1535 		overlay->alpha.interpolateTo(1, trans);
1536 		core->main(trans);
1537 	}
1538 
1539 	removeRenderObject(loading);
1540 	loading = 0;
1541 	removeRenderObject(sidel);
1542 	removeRenderObject(sider);
1543 	removeRenderObject(label);
1544 	removeRenderObject(tube);
1545 
1546 	if (useFrameBuffer && core->frameBuffer.isInited())
1547 		core->afterEffectManager = new AfterEffectManager(vars->afterEffectsXDivs,vars->afterEffectsYDivs);
1548 	else
1549 		core->afterEffectManager = 0;
1550 
1551 	setInputGrab(1);
1552 
1553 	/*
1554 	removeRenderObject(disk);
1555 	disk = 0;
1556 	*/
1557 
1558 	bindInput();
1559 
1560 	// Go directly to the title in dev mode
1561 	if(isDeveloperKeys())
1562 		title();
1563 	else
1564 		enqueueJumpState("BitBlotLogo");
1565 }
1566 
recreateBlackBars()1567 void DSQ::recreateBlackBars()
1568 {
1569 	bool useOldAlpha=false;
1570 	InterpolatedVector abar_left, abar_right, abarFade_left, abarFade_right;
1571 
1572 	if (bar_left)
1573 	{
1574 		useOldAlpha = true;
1575 		abar_left = bar_left->alpha;
1576 		removeRenderObject(bar_left);
1577 	}
1578 	if (bar_right)
1579 	{
1580 		abar_right = bar_right->alpha;
1581 		removeRenderObject(bar_right);
1582 	}
1583 	if (barFade_left)
1584 	{
1585 		abarFade_left = barFade_left->alpha;
1586 		removeRenderObject(barFade_left);
1587 	}
1588 	if (barFade_right)
1589 	{
1590 		abarFade_right = barFade_right->alpha;
1591 		removeRenderObject(barFade_right);
1592 	}
1593 	if (bar_up)
1594 		removeRenderObject(bar_up);
1595 	if (bar_down)
1596 		removeRenderObject(bar_down);
1597 
1598 	bar_left = bar_right = bar_up = bar_down = barFade_left = barFade_right = 0;
1599 
1600 	if (getVirtualWidth() > 800)
1601 	{
1602 		int sz2 = (core->getVirtualWidth() - baseVirtualWidth)/2.0f;
1603 
1604 		bar_left = new Quad;
1605 		{
1606 			bar_left->position = Vector(-sz2, 300);
1607 			bar_left->setWidthHeight(sz2*2, 600);
1608 			bar_left->color = 0;
1609 			bar_left->followCamera = 1;
1610 			bar_left->cull = 0;
1611 		}
1612 		addRenderObject(bar_left, LR_BLACKBARS);
1613 
1614 		bar_right = new Quad;
1615 		{
1616 			bar_right->position = Vector(800 + sz2, 300);
1617 			bar_right->setWidthHeight(sz2*2, 600);
1618 			bar_right->color = 0;
1619 			bar_right->followCamera = 1;
1620 			bar_right->cull = 0;
1621 		}
1622 		addRenderObject(bar_right, LR_BLACKBARS);
1623 
1624 		barFade_left = new Quad;
1625 		{
1626 			barFade_left->setTexture("gui/edge");
1627 			barFade_left->position = Vector(16, 300);
1628 			barFade_left->setWidthHeight(34, 620);
1629 			barFade_left->color = 0;
1630 			barFade_left->followCamera = 1;
1631 			barFade_left->cull = 0;
1632 		}
1633 		addRenderObject(barFade_left, LR_BLACKBARS);
1634 
1635 		barFade_right = new Quad;
1636 		{
1637 			barFade_right->setTexture("gui/edge");
1638 			barFade_right->flipHorizontal();
1639 			barFade_right->position = Vector(800-16, 300);
1640 			barFade_right->setWidthHeight(34, 620);
1641 			barFade_right->color = 0;
1642 			barFade_right->followCamera = 1;
1643 			barFade_right->cull = 0;
1644 		}
1645 		addRenderObject(barFade_right, LR_BLACKBARS);
1646 
1647 		if (useOldAlpha)
1648 		{
1649 			bar_left->alpha = abar_left;
1650 			bar_right->alpha = abar_right;
1651 			barFade_left->alpha = abarFade_left;
1652 			barFade_right->alpha = abarFade_right;
1653 		}
1654 		else
1655 		{
1656 			bar_right->alpha = 0;
1657 			bar_left->alpha = 0;
1658 			barFade_right->alpha = 0;
1659 			barFade_left->alpha = 0;
1660 		}
1661 	}
1662 
1663 	// top and bottom bars are not toggle-able, they will always be on if they are needed
1664 	if (getVirtualHeight() > 600)
1665 	{
1666 		int sz2 = (core->getVirtualHeight() - baseVirtualHeight)/2.0f;
1667 		bar_up = new Quad;
1668 		{
1669 			bar_up->position = Vector(400, -sz2);
1670 			bar_up->setWidthHeight(800, sz2*2);
1671 			bar_up->color = 0;
1672 			bar_up->followCamera = 1;
1673 			bar_up->cull = 0;
1674 		}
1675 		addRenderObject(bar_up, LR_BLACKBARS);
1676 
1677 		bar_down = new Quad;
1678 		{
1679 			bar_down->position = Vector(400, 600 + sz2);
1680 			bar_down->setWidthHeight(800, sz2*2);
1681 			bar_down->color = 0;
1682 			bar_down->followCamera = 1;
1683 			bar_down->cull = 0;
1684 		}
1685 		addRenderObject(bar_down, LR_BLACKBARS);
1686 	}
1687 }
1688 
setBlackBarsColor(Vector color)1689 void DSQ::setBlackBarsColor(Vector color)
1690 {
1691 	if (bar_left && bar_right)
1692 	{
1693 		bar_left->color = bar_right->color = barFade_left->color = barFade_right->color = color;
1694 	}
1695 }
1696 
toggleBlackBars(bool on,float t)1697 void DSQ::toggleBlackBars(bool on, float t)
1698 {
1699 	if (bar_left && bar_right)
1700 	{
1701 		if (on)
1702 		{
1703 			bar_left->alpha = bar_right->alpha = 1;
1704 			barFade_right->alpha = barFade_left->alpha = 1;
1705 		}
1706 		else
1707 		{
1708 			if (t != 0)
1709 			{
1710 				bar_left->alpha.interpolateTo(0, t);
1711 				bar_right->alpha.interpolateTo(0, t);
1712 				barFade_left->alpha.interpolateTo(0, t);
1713 				barFade_right->alpha.interpolateTo(0, t);
1714 			}
1715 			else
1716 			{
1717 				bar_left->alpha = bar_right->alpha = 0;
1718 				barFade_right->alpha = barFade_left->alpha = 0;
1719 			}
1720 		}
1721 	}
1722 }
1723 
toggleInputGrabPlat(bool on)1724 void DSQ::toggleInputGrabPlat(bool on)
1725 {
1726 }
1727 
instantQuit()1728 void DSQ::instantQuit()
1729 {
1730 	if (core->getCtrlState() && core->getAltState())
1731 		Core::instantQuit();
1732 }
1733 
getEntityLayerToLayer(int lcode)1734 int DSQ::getEntityLayerToLayer(int lcode)
1735 {
1736 	if (lcode == -4)
1737 		return LR_ENTITIES_MINUS4; // in front of elements11
1738 	else if (lcode == -3)
1739 		return LR_ENTITIES_MINUS3; // in front of elements2
1740 	else if (lcode == -2)
1741 		return LR_ENTITIES_MINUS2; // in front of elements3
1742 	else if (lcode == -1)
1743 		return LR_ENTITIES0;
1744 	else if (lcode == -100)
1745 		return LR_ENTITIES00;
1746 	else if (lcode == 0)
1747 		return LR_ENTITIES;
1748 	else if (lcode == 1)
1749 		return LR_ENTITIES2;
1750 	else if (lcode == 2)
1751 		return LR_DARK_LAYER;
1752 	std::ostringstream os;
1753 	os << "Invalid entity layer code: " << lcode;
1754 	debugLog(os.str());
1755 	return 0;
1756 }
1757 
setFilter(int ds)1758 void DSQ::setFilter(int ds)
1759 {
1760 	dsq_filter = ds;
1761 	if (dsq_filter == 0)
1762 	{
1763 		Texture::filter = GL_LINEAR;
1764 	}
1765 	else if (dsq_filter == 2)
1766 	{
1767 		Texture::filter = GL_NEAREST;
1768 	}
1769 }
1770 
setStory()1771 void DSQ::setStory()
1772 {
1773 	std::string flagString = getUserInputString(dsq->continuity.stringBank.get(2014), "0");
1774 	int flag = 0;
1775 	std::istringstream is(flagString);
1776 	is >> flag;
1777 
1778 	core->main(0.2);
1779 	std::ostringstream os;
1780 	os << dsq->continuity.getFlag(flag);
1781 	flagString = getUserInputString(dsq->continuity.stringBank.get(2015), os.str());
1782 	int value = 0;
1783 	std::istringstream is2(flagString);
1784 	is2 >> value;
1785 	dsq->continuity.setFlag(flag, value);
1786 }
1787 
getNoteVector(int note,float mag)1788 Vector DSQ::getNoteVector(int note, float mag)
1789 {
1790 	Vector vec;
1791 	switch(note)
1792 	{
1793 	case 0:
1794 		vec = Vector(0,1);
1795 	break;
1796 	case 1:
1797 		vec = Vector(0.5, 0.5);
1798 	break;
1799 	case 2:
1800 		vec = Vector(1, 0);
1801 	break;
1802 	case 3:
1803 		vec = Vector(0.5, -0.5);
1804 	break;
1805 	case 4:
1806 		vec = Vector(0, -1);
1807 	break;
1808 	case 5:
1809 		vec = Vector(-0.5, -0.5);
1810 	break;
1811 	case 6:
1812 		vec = Vector(-1, 0);
1813 	break;
1814 	case 7:
1815 		vec = Vector(-0.5, 0.5);
1816 	break;
1817 	}
1818 	return vec*mag;
1819 }
1820 
getRandNote()1821 int DSQ::getRandNote()
1822 {
1823 	static int lastRand = -1;
1824 
1825 	int r = rand()%8;
1826 
1827 	int c = 0;
1828 	while (r == lastRand)
1829 	{
1830 		r = rand()%8;
1831 		c++;
1832 		if (c > 8) break;
1833 	}
1834 	lastRand = r;
1835 	/*
1836 	static std::vector<int> lastRand;
1837 
1838 	int r = -1;
1839 	int c = 0;
1840 
1841 	while (r == -1 && c < 8)
1842 	{
1843 		r = rand()%8;
1844 		for (int i = 0; i < lastRand.size(); i++)
1845 		{
1846 			if (lastRand[i] == r)
1847 			{
1848 				r = -1;
1849 				break;
1850 			}
1851 		}
1852 		c++;
1853 	}
1854 
1855 	if (r == -1)
1856 		r = rand()%8;
1857 
1858 	std::ostringstream os;
1859 	os << "r: " << r;
1860 	debugLog(os.str());
1861 
1862 	lastRand.push_back(r);
1863 
1864 	if (lastRand.size() > 4)
1865 		lastRand.resize(4);
1866 	*/
1867 
1868 	return r;
1869 }
1870 
getNoteColor(int note)1871 Vector DSQ::getNoteColor(int note)
1872 {
1873 	Vector noteColor;
1874 	switch(note)
1875 	{
1876 	case 0:
1877 		// light green
1878 		noteColor = Vector(0.5, 1, 0.5);
1879 	break;
1880 	case 1:
1881 		// blue/green
1882 		noteColor = Vector(0.5, 1, 0.75);
1883 	break;
1884 	case 2:
1885 		// blue
1886 		noteColor = Vector(0.5, 0.5, 1);
1887 	break;
1888 	case 3:
1889 		// purple
1890 		noteColor = Vector(1, 0.5, 1);
1891 	break;
1892 	case 4:
1893 		// red
1894 		noteColor = Vector(1, 0.5, 0.5);
1895 	break;
1896 	case 5:
1897 		// red/orange
1898 		noteColor = Vector(1, 0.6, 0.5);
1899 	break;
1900 	case 6:
1901 		// orange
1902 		noteColor = Vector(1, 0.75, 0.5);
1903 	break;
1904 	case 7:
1905 		// orange
1906 		noteColor = Vector(1, 1, 0.5);
1907 	break;
1908 	}
1909 	return noteColor;
1910 }
1911 
toggleVersionLabel(bool on)1912 void DSQ::toggleVersionLabel(bool on)
1913 {
1914 	float a = 0;
1915 	if (on)
1916 		a = 1;
1917 
1918 	versionLabel->alpha.interpolateTo(a, 1);
1919 }
1920 
toggleInputMode()1921 void DSQ::toggleInputMode()
1922 {
1923 	switch(inputMode)
1924 	{
1925 	case INPUT_MOUSE:
1926 		setInputMode(INPUT_JOYSTICK);
1927 	break;
1928 	case INPUT_JOYSTICK:
1929 		setInputMode(INPUT_MOUSE);
1930 	break;
1931 	}
1932 }
1933 
setInputMode(InputMode mode)1934 void DSQ::setInputMode(InputMode mode)
1935 {
1936 	inputMode = mode;
1937 	switch(inputMode)
1938 	{
1939 	case INPUT_JOYSTICK:
1940 		core->joystickAsMouse = true;
1941 		updateCursorFromMouse = false;
1942 	break;
1943 	case INPUT_MOUSE:
1944 		setMousePosition(core->mouse.position);
1945 		core->joystickAsMouse = false;
1946 		updateCursorFromMouse = true;
1947 	break;
1948 	}
1949 }
1950 
toggleRenderCollisionShapes()1951 void DSQ::toggleRenderCollisionShapes()
1952 {
1953 	if (core->getCtrlState() && core->getShiftState())
1954 		RenderObject::renderCollisionShape = !RenderObject::renderCollisionShape;
1955 }
1956 
takeScreenshot()1957 void DSQ::takeScreenshot()
1958 {
1959 	//takeScreenShot();
1960 	doScreenshot = true;
1961 	//saveScreenshotTGA("screen.tga");
1962 }
1963 
unloadDevice()1964 void DSQ::unloadDevice()
1965 {
1966 	destroyFonts();
1967 
1968 	Core::unloadDevice();
1969 	darkLayer.unloadDevice();
1970 }
1971 
reloadDevice()1972 void DSQ::reloadDevice()
1973 {
1974 	loadFonts();
1975 
1976 	Core::reloadDevice();
1977 	darkLayer.reloadDevice();
1978 
1979 	recreateBlackBars();
1980 }
1981 
1982 #ifdef AQUARIA_BUILD_CONSOLE
toggleConsole()1983 void DSQ::toggleConsole()
1984 {
1985 	if (console && isDeveloperKeys())
1986 	{
1987 		if (console->alpha == 0)
1988 		{
1989 			console->alpha.interpolateTo(1, 0.1);
1990 			cmDebug->alpha.interpolateTo(1, 0.1);
1991 			fpsText->alpha.interpolateTo(1, 0.1);
1992 			if (profRender)
1993 				profRender->alpha.interpolateTo(1, 0.1);
1994 			RenderObject::renderPaths = true;
1995 		}
1996 		else if (console->alpha == 1)
1997 		{
1998 			console->alpha.interpolateTo(0, 0.1);
1999 			cmDebug->alpha.interpolateTo(0, 0.1);
2000 			fpsText->alpha.interpolateTo(0, 0.1);
2001 			if (profRender)
2002 				profRender->alpha.interpolateTo(0, 0.1);
2003 			RenderObject::renderPaths = false;
2004 		}
2005 	}
2006 }
2007 
debugLog(const std::string & s)2008 void DSQ::debugLog(const std::string &s)
2009 {
2010 	consoleLines.push_back(s);
2011 	if (consoleLines.size() > MAX_CONSOLELINES)
2012 	{
2013 		//consoleLines.size()-MAX_CONSOLELINES
2014 		for (int i = 0; i < consoleLines.size()-1; i++)
2015 		{
2016 			consoleLines[i] = consoleLines[i+1];
2017 		}
2018 		consoleLines.resize(MAX_CONSOLELINES);
2019 	}
2020 	if (console)
2021 	{
2022 		std::string text;
2023 		for (int i = 0; i < consoleLines.size(); i++)
2024 		{
2025 			text += consoleLines[i] + '\n';
2026 		}
2027 		console->setText(text);
2028 	}
2029 	Core::debugLog(s);
2030 }
2031 #endif  // AQUARIA_BUILD_CONSOLE
2032 
getEntityTypeIndexByName(std::string s)2033 int DSQ::getEntityTypeIndexByName(std::string s)
2034 {
2035 	for (int i = 0; i < game->entityTypeList.size(); i++)
2036 	{
2037 		EntityClass *t = &game->entityTypeList[i];
2038 		if (t->name == s)
2039 			return t->idx;
2040 	}
2041 	return -1;
2042 }
2043 
toggleMuffleSound(bool toggle)2044 void DSQ::toggleMuffleSound(bool toggle)
2045 {
2046 	/*
2047 	if (sound->isPlayingMusic())
2048 	{
2049 	#ifdef BBGE_BUILD_WINDOWS
2050 		if (toggle)
2051 		{
2052 			BASS_ChannelSetFX(sound->getMusicStream(), 1, BASS_FX_FLANGER);
2053 			BASS_FXREVERB rev;
2054 			rev.fHighFreqRTRatio = 0;
2055 			rev.fInGain = 0;
2056 			rev.fReverbMix = 0.001;
2057 			rev.fReverbTime = 1000;
2058 			BASS_FXSetParameters(sound->getMusicStream(), &rev);
2059 		}
2060 		else
2061 			BASS_ChannelRemoveFX(sound->getMusicStream(), BASS_FX_DISTORTION);
2062 	#endif
2063 
2064 	}
2065 	*/
2066 }
2067 
loadModsCallback(const std::string & filename,intptr_t param)2068 void DSQ::loadModsCallback(const std::string &filename, intptr_t param)
2069 {
2070 	//errorLog(filename);
2071 	int pos = filename.find_last_of('/')+1;
2072 	int pos2 = filename.find_last_of('.');
2073 	std::string name = filename.substr(pos, pos2-pos);
2074 	ModEntry m;
2075 	m.path = name;
2076 	m.id = dsq->modEntries.size();
2077 
2078 	XMLDocument d;
2079 	if(!Mod::loadModXML(&d, name))
2080 	{
2081 		std::ostringstream os;
2082 		os << "Failed to load mod xml: " << filename << " -- Error: " << d.ErrorStr();
2083 		dsq->debugLog(os.str());
2084 		return;
2085 	}
2086 
2087 	m.type = Mod::getTypeFromXML(d.FirstChildElement("AquariaMod"));
2088 
2089 	dsq->modEntries.push_back(m);
2090 
2091 	std::ostringstream ss;
2092 	ss << "Loaded ModEntry [" << m.path << "] -> " << m.id << "  | type " << m.type;
2093 
2094 	dsq->debugLog(ss.str());
2095 }
2096 
loadModPackagesCallback(const std::string & filename,intptr_t param)2097 void DSQ::loadModPackagesCallback(const std::string &filename, intptr_t param)
2098 {
2099 	bool ok = dsq->mountModPackage(filename);
2100 
2101 	std::ostringstream ss;
2102 	ss << "Mount Mod Package '" << filename << "' : " << (ok ? "ok" : "FAIL");
2103 	dsq->debugLog(ss.str());
2104 
2105 	// they will be enumerated by the following loadModsCallback round
2106 }
2107 
startSelectedMod()2108 void DSQ::startSelectedMod()
2109 {
2110 	ModEntry *e = getSelectedModEntry();
2111 	if (e)
2112 	{
2113 		clearModSelector();
2114 		mod.load(e->path);
2115 		mod.start();
2116 
2117 		/*
2118 		if (dsq->game->sceneToLoad.empty())
2119 		{
2120 			mod.setActive(false);
2121 		}
2122 		*/
2123 	}
2124 }
2125 
getSelectedModEntry()2126 ModEntry* DSQ::getSelectedModEntry()
2127 {
2128 	if (!modEntries.empty() && selectedMod >= 0 && selectedMod < modEntries.size())
2129 		return &modEntries[selectedMod];
2130 	return 0;
2131 }
2132 
loadMods()2133 void DSQ::loadMods()
2134 {
2135 	modEntries.clear();
2136 
2137 	std::string modpath = mod.getBaseModPath();
2138 	debugLog("loadMods: " + modpath);
2139 
2140 #ifdef BBGE_BUILD_VFS
2141 	// first load the packages, then enumerate XMLs
2142 	forEachFile(modpath, ".aqmod", loadModPackagesCallback, 0);
2143 #endif
2144 
2145 	forEachFile(modpath, ".xml", loadModsCallback, 0);
2146 	selectedMod = 0;
2147 
2148 	std::ostringstream os;
2149 	os << "loadMods done, " << modEntries.size() << " entries";
2150 	debugLog(os.str());
2151 }
2152 
applyPatches()2153 void DSQ::applyPatches()
2154 {
2155 #ifndef AQUARIA_DEMO
2156 #ifdef BBGE_BUILD_VFS
2157 
2158 	// This is to allow files in patches to override files in mods on non-win32 systems
2159 	vfs.Mount(mod.getBaseModPath().c_str(), "_mods");
2160 
2161 	loadMods();
2162 
2163 	for (std::set<std::string>::iterator it = activePatches.begin(); it != activePatches.end(); ++it)
2164 		for(int i = 0; i < modEntries.size(); ++i)
2165 			if(modEntries[i].type == MODTYPE_PATCH)
2166 				if(!nocasecmp(modEntries[i].path.c_str(), it->c_str()))
2167 					applyPatch(modEntries[i].path);
2168 #endif
2169 #endif
2170 }
2171 
2172 
2173 #ifdef BBGE_BUILD_VFS
2174 
refr_pushback(ttvfs::DirBase * vd,void * user)2175 static void refr_pushback(ttvfs::DirBase *vd, void *user)
2176 {
2177 	std::list<std::string> *li = (std::list<std::string>*)user;
2178 	li->push_back(vd->fullname());
2179 }
2180 
refr_insert(VFILE * vf,void * user)2181 static void refr_insert(VFILE *vf, void *user)
2182 {
2183 	// texture names are like: "naija/naija2-frontleg3" - no .png extension, and no gfx/ path
2184 	std::set<std::string>*files = (std::set<std::string>*)user;
2185 	std::string t = vf->fullname();
2186 	size_t dotpos = t.rfind('.');
2187 	size_t pathstart = t.find("gfx/");
2188 	if(dotpos == std::string::npos || pathstart == std::string::npos || dotpos < pathstart)
2189 		return; // whoops
2190 
2191 	files->insert(t.substr(pathstart + 4, dotpos - (pathstart + 4)));
2192 }
2193 
2194 
2195 // this thing is rather heuristic... but works for normal mod paths
2196 // there is apparently nothing else except Textures that is a subclass of Resource,
2197 // thus directly using "gfx" subdir should be fine...
refreshResourcesForPatch(const std::string & name)2198 void DSQ::refreshResourcesForPatch(const std::string& name)
2199 {
2200 	std::list<std::string> left;
2201 	std::set<std::string> files;
2202 	left.push_back(mod.getBaseModPath() + name + "/gfx");
2203 	ttvfs::DirView view;
2204 	do
2205 	{
2206 		std::string dirname = left.front();
2207 		left.pop_front();
2208 		if(vfs.FillDirView(dirname.c_str(), view))
2209 		{
2210 			view.forEachDir(refr_pushback, &left);
2211 			view.forEachFile(refr_insert, &files);
2212 		}
2213 	}
2214 	while(left.size());
2215 
2216 	std::ostringstream os;
2217 	os << "refreshResourcesForPatch - " << files.size() << " to refresh";
2218 	debugLog(os.str());
2219 
2220 	int reloaded = 0;
2221 	if(files.size())
2222 	{
2223 		for(int i = 0; i < dsq->resources.size(); ++i)
2224 		{
2225 			Texture *r = dsq->resources[i];
2226 			if(files.find(r->name) != files.end())
2227 				r->reload();
2228 		}
2229 	}
2230 	os.str("");
2231 	os << "refreshResourcesForPatch - " << reloaded << " textures reloaded";
2232 	debugLog(os.str());
2233 }
2234 #else
refreshResourcesForPatch(const std::string & name)2235 void DSQ::refreshResourcesForPatch(const std::string& name) {}
2236 #endif
2237 
applyPatch(const std::string & name)2238 void DSQ::applyPatch(const std::string& name)
2239 {
2240 #ifdef BBGE_BUILD_VFS
2241 #ifdef AQUARIA_DEMO
2242 	return;
2243 #endif
2244 
2245 	std::string src = mod.getBaseModPath();
2246 	src += name;
2247 	debugLog("Apply patch: " + src);
2248 	vfs.Mount(src.c_str(), "");
2249 
2250 	activePatches.insert(name);
2251 	refreshResourcesForPatch(name);
2252 #endif
2253 }
2254 
unapplyPatch(const std::string & name)2255 void DSQ::unapplyPatch(const std::string& name)
2256 {
2257 #ifdef BBGE_BUILD_VFS
2258 	std::string src = mod.getBaseModPath();
2259 	src += name;
2260 	debugLog("Unapply patch: " + src);
2261 	vfs.Unmount(src.c_str(), "");
2262 
2263 	activePatches.erase(name);
2264 	refreshResourcesForPatch(name);
2265 #endif
2266 }
2267 
playMenuSelectSfx()2268 void DSQ::playMenuSelectSfx()
2269 {
2270 	core->sound->playSfx("MenuSelect");
2271 }
2272 
playPositionalSfx(const std::string & name,const Vector & position,float f,float fadeOut,SoundHolder * holder)2273 void DSQ::playPositionalSfx(const std::string &name, const Vector &position, float f, float fadeOut, SoundHolder *holder)
2274 {
2275 	PlaySfx sfx;
2276 	sfx.freq = f;
2277 	sfx.name = name;
2278 	sfx.relative = false;
2279 	sfx.positional = true;
2280 	sfx.x = position.x;
2281 	sfx.y = position.y;
2282 
2283 	void *c = sound->playSfx(sfx);
2284 
2285 	if (fadeOut != 0)
2286 		sound->fadeSfx(c, SFT_OUT, fadeOut);
2287 
2288 	if (holder)
2289 		holder->linkSound(c);
2290 }
2291 
shutdown()2292 void DSQ::shutdown()
2293 {
2294 	mod.stop();
2295 
2296 	Network::shutdown();
2297 
2298 	scriptInterface.shutdown();
2299 	precacher.clean();
2300 	/*
2301 	if (title)delete title;
2302 	if (game) delete game;
2303 	if (logo) delete logo;
2304 	if (gameOver) delete gameOver;
2305 	if (scLogo)	delete scLogo;
2306 	if (introText)	delete introText;
2307 	if (animationEditor) delete animationEditor;
2308 	if (intro)		delete intro;
2309 	*/
2310 
2311 	core->particleManager->clearParticleBank();
2312 	Shot::clearShotBank();
2313 	SkeletalSprite::clearCache();
2314 
2315 
2316 	cursor->setTexturePointer(0);
2317 
2318 	UNREFTEX(texCursor);
2319 	UNREFTEX(texCursorSwim);
2320 	UNREFTEX(texCursorBurst);
2321 	UNREFTEX(texCursorSing);
2322 	UNREFTEX(texCursorLook);
2323 
2324 #ifdef AQUARIA_BUILD_CONSOLE
2325 	removeRenderObject(console);
2326 	console = 0;
2327 #endif
2328 	removeRenderObject(cmDebug);
2329 	cmDebug = 0;
2330 	removeRenderObject(subtext);
2331 	subtext = 0;
2332 	removeRenderObject(subbox);
2333 	subbox = 0;
2334 
2335 #ifdef BBGE_BUILD_ACHIEVEMENTS_INTERNAL
2336 	removeRenderObject(achievement_text);
2337 	achievement_text = 0;
2338 	removeRenderObject(achievement_box);
2339 	achievement_box = 0;
2340 #endif
2341 
2342 	removeRenderObject(cursor);
2343 	removeRenderObject(cursorGlow); // is this necessary? probably
2344 	removeRenderObject(cursorBlinker);
2345 	removeRenderObject(overlay);
2346 	removeRenderObject(overlay2);
2347 	removeRenderObject(overlay3);
2348 	removeRenderObject(overlayRed);
2349 	removeRenderObject(tfader);
2350 	//removeRenderObject(messageLabelBG);
2351 	removeRenderObject(fpsText);
2352 
2353 	if (bar_left)
2354 		removeRenderObject(bar_left);
2355 	if (bar_right)
2356 		removeRenderObject(bar_right);
2357 	if (barFade_left)
2358 		removeRenderObject(barFade_left);
2359 	if (barFade_right)
2360 		removeRenderObject(barFade_right);
2361 	if (bar_up)
2362 		removeRenderObject(bar_up);
2363 	if (bar_down)
2364 		removeRenderObject(bar_down);
2365 
2366 	if (cutscene_bg)
2367 		removeRenderObject(cutscene_bg);
2368 	if (cutscene_text)
2369 		removeRenderObject(cutscene_text);
2370 	if (cutscene_text2)
2371 		removeRenderObject(cutscene_text2);
2372 
2373 
2374 	removeRenderObject(versionLabel);
2375 	versionLabel = 0;
2376 
2377 	if (profRender)
2378 		removeRenderObject(profRender);
2379 
2380 	if (screenTransition)
2381 	{
2382 		screenTransition->destroy();
2383 		removeRenderObject(screenTransition);
2384 	}
2385 
2386 	destroyFonts();
2387 
2388 
2389 	screenTransition = 0;
2390 
2391 	core->main(0.1);
2392 	overlay = 0;
2393 	overlay2 = 0;
2394 	overlay3 = 0;
2395 	cursor = 0;
2396 	tfader = 0;
2397 
2398 	continuity.shutdown();
2399 
2400 	//script.shutdown();
2401 	Core::shutdown();
2402 }
2403 
setTexturePointers()2404 void DSQ::setTexturePointers()
2405 {
2406 	texCursor = core->addTexture("cursor");
2407 	texCursorLook = core->addTexture("cursor-look");
2408 	texCursorBurst = core->addTexture("cursor-burst");
2409 	texCursorSwim = core->addTexture("cursor-swim");
2410 	texCursorSing = core->addTexture("cursor-sing");
2411 
2412 	if (cursor)
2413 		cursor->setTexturePointer(texCursor);
2414 }
2415 
setCursor(CursorType type)2416 void DSQ::setCursor(CursorType type)
2417 {
2418 	switch(type)
2419 	{
2420 	case CURSOR_NORMAL:
2421 		cursor->setTexturePointer(texCursor);
2422 	break;
2423 	case CURSOR_LOOK:
2424 		cursor->setTexturePointer(texCursorLook);
2425 	break;
2426 	case CURSOR_BURST:
2427 		cursor->setTexturePointer(texCursorBurst);
2428 	break;
2429 	case CURSOR_SWIM:
2430 		cursor->setTexturePointer(texCursorSwim);
2431 	break;
2432 	case CURSOR_SING:
2433 		cursor->setTexturePointer(texCursorSing);
2434 	break;
2435 	default:
2436 		cursor->setTexturePointer(texCursor);
2437 	break;
2438 	}
2439 }
2440 
toggleEffects()2441 void DSQ::toggleEffects()
2442 {
2443 	/*
2444 	static int tester = 0;
2445 	float t = 3;
2446 	if (!tester)
2447 		sound->crossover("battletest-town", t);
2448 	else
2449 		sound->crossover("battletest-battle", t);
2450 	tester = !tester;
2451 	*/
2452 	/*
2453 	static int effectToggler = 0;
2454 	effectToggler ++;
2455 	switch (effectToggler)
2456 	{
2457 	case 1:
2458 		postProcessingFx.enable(FXT_RADIALBLUR);
2459 		postProcessingFx.radialBlurColor = Vector(1,1,1);
2460 		postProcessingFx.intensity = 0.1;
2461 	break;
2462 	case 2:
2463 		postProcessingFx.intensity = 0.05;
2464 	break;
2465 	case 3:
2466 		postProcessingFx.intensity = 0.2;
2467 	break;
2468 	case 4:
2469 		postProcessingFx.intensity = 0.4;
2470 	break;
2471 	default:
2472 	case 0:
2473 		effectToggler = 0;
2474 		postProcessingFx.disable(FXT_RADIALBLUR);
2475 
2476 	break;
2477 	}
2478 	*/
2479 }
2480 
clickRingEffect(Vector pos,int type,Vector color,float ut)2481 void DSQ::clickRingEffect(Vector pos, int type, Vector color, float ut)
2482 {
2483 	switch(type)
2484 	{
2485 	case 0:
2486 		{
2487 			float t = 0.5;
2488 			if (ut != 0) t = ut;
2489 			Quad *q = new Quad;
2490 			q->setTexture("Particles/SoftRing");
2491 			q->setWidthHeight(100, 100);
2492 			q->scale = Vector(1,1);
2493 			q->scale.interpolateTo(Vector(5,5), t);
2494 
2495 			q->color = color;
2496 
2497 			q->setBlendType(RenderObject::BLEND_ADD);
2498 
2499 			q->alpha.ensureData();
2500 			q->alpha.data->path.addPathNode(0, 0);
2501 			q->alpha.data->path.addPathNode(0.5, 0.1);
2502 			q->alpha.data->path.addPathNode(0.5, 0.5);
2503 			q->alpha.data->path.addPathNode(0, 1);
2504 			q->alpha.startPath(t);
2505 
2506 			q->position = pos;
2507 
2508 			q->followCamera = 1;
2509 
2510 			q->setLife(t);
2511 
2512 			getTopStateData()->addRenderObject(q, LR_WORLDMAPHUD);
2513 		}
2514 		break;
2515 	case 1:
2516 		{
2517 			float t = 0.2;
2518 			if (ut != 0) t = ut;
2519 			Quad *q = new Quad;
2520 			q->setTexture("Particles/SoftRing");
2521 			q->setWidthHeight(100, 100);
2522 			q->scale = Vector(5,5);
2523 			q->scale.interpolateTo(Vector(1,1), t);
2524 
2525 			q->setBlendType(RenderObject::BLEND_ADD);
2526 
2527 			q->color = color;
2528 
2529 			q->alpha.ensureData();
2530 			q->alpha.data->path.addPathNode(0, 0);
2531 			q->alpha.data->path.addPathNode(0.5, 0.1);
2532 			q->alpha.data->path.addPathNode(0.5, 0.5);
2533 			q->alpha.data->path.addPathNode(0, 1);
2534 			q->alpha.startPath(t);
2535 
2536 			q->position = pos;
2537 
2538 			q->followCamera = 1;
2539 
2540 			q->setLife(t);
2541 
2542 			getTopStateData()->addRenderObject(q, LR_WORLDMAPHUD);
2543 		}
2544 		break;
2545 	}
2546 }
2547 
getEntityByName(const std::string & name)2548 Entity *DSQ::getEntityByName(const std::string& name)
2549 {
2550 	Entity *e = 0;
2551 	FOR_ENTITIES(i)
2552 	{
2553 		e = (*i);
2554 
2555 		if (e->life == 1 && (nocasecmp(e->name, name)==0))
2556 		{
2557 			break;
2558 		}
2559 		e = 0;
2560 	}
2561 	return e;
2562 }
2563 
2564 // HACK: warning SLOW!
2565 // really?
getEntityByNameNoCase(std::string name)2566 Entity *DSQ::getEntityByNameNoCase(std::string name)
2567 {
2568 	stringToUpper(name);
2569 	Entity *e = 0;
2570 	FOR_ENTITIES(i)
2571 	{
2572 		e = (*i);
2573 
2574 		std::string check =  e->name;
2575 		stringToUpper(check);
2576 		if (e->life == 1 && check == name)
2577 		{
2578 			break;
2579 		}
2580 		e = 0;
2581 	}
2582 	return e;
2583 }
2584 
doLoadMenu()2585 void DSQ::doLoadMenu()
2586 {
2587 	doSaveSlotMenu(SSM_LOAD);
2588 	if (selectedSaveSlot != 0)
2589 	{
2590 		//loaded = true;
2591 		dsq->doScreenTrans = true;
2592 	}
2593 	else
2594 	{
2595 		//loaded = false;
2596 		clearSaveSlots(true);
2597 	}
2598 }
2599 
doSavePoint(const Vector & position)2600 void DSQ::doSavePoint(const Vector &position)
2601 {
2602 //	if (!e) return;
2603 
2604 	dsq->game->avatar->setv(EV_LOOKAT, 0);
2605 	core->sound->playSfx("MemoryCrystalActivate");
2606 
2607 	Quad *glow = new Quad;
2608 	{
2609 		glow->setTexture("save-point-glow");
2610 		glow->alpha = 0;
2611 		glow->alpha.interpolateTo(0.5, 1, 1, -1, 1);
2612 		glow->setBlendType(RenderObject::BLEND_ADD);
2613 		glow->position = position;
2614 		glow->scale = Vector(1,1)*1.25f;
2615 		glow->setLife(3);
2616 		glow->setDecayRate(1);
2617 	}
2618 	addRenderObject(glow, LR_LIGHTING);
2619 
2620 	dsq->game->avatar->idle();
2621 	dsq->game->avatar->vel=0;
2622 	dsq->game->avatar->disableInput();
2623 	dsq->game->avatar->fhTo(false);
2624 	dsq->game->avatar->position.interpolateTo(position, 1, 0, 0, 1);
2625 	dsq->game->avatar->myZoom.interpolateTo(Vector(1,1),0.5);
2626 	// override =
2627 	dsq->game->avatar->skeletalSprite.animate("save", 0, 3);
2628 	dsq->game->clearControlHint();
2629 	dsq->main(2);
2630 	dsq->game->avatar->enableInput();
2631 	dsq->game->avatar->revive();
2632 	dsq->game->togglePause(1);
2633 	dsq->doSaveSlotMenu(SSM_SAVE, position);
2634 	dsq->game->togglePause(0);
2635 	core->resetTimer();
2636 	dsq->game->avatar->setv(EV_LOOKAT, 1);
2637 	//dsq->game->avatar->skeletalSprite.animate("unsave", 0, 3);
2638 	//dsq->continuity.saveFile(0);
2639 }
2640 
playNoEffect()2641 void DSQ::playNoEffect()
2642 {
2643 	if (noEffectTimer <= 0)
2644 	{
2645 		sound->playSfx("noeffect", 0.9);
2646 		noEffectTimer = 0.2;
2647 	}
2648 }
2649 
clearMenu(float t)2650 void DSQ::clearMenu(float t)
2651 {
2652 	for (int i = 0; i < menu.size(); i++)
2653 	{
2654 		menu[i]->setLife(1);
2655 		menu[i]->setDecayRate(1/t);
2656 		menu[i]->fadeAlphaWithLife = 1;
2657 		//menu[i]->alpha.interpolateTo(0, 0.5);
2658 	}
2659 	menu.clear();
2660 }
2661 
screenMessage(const std::string & msg)2662 void DSQ::screenMessage(const std::string &msg)
2663 {
2664 	debugLog(msg);
2665 
2666 	DebugFont *b = new DebugFont();
2667 	b->position = Vector(16,300);
2668 	b->setFontSize(10);
2669 	b->setText(msg);
2670 	b->alpha = 0;
2671 	b->alpha.interpolateTo(1, 0.75, 1, 1);
2672 	b->followCamera= 1;
2673 	b->setLife(2);
2674 	b->setDecayRate(1);
2675 	core->getTopStateData()->addRenderObject(b, LR_DEBUG_TEXT);
2676 
2677 	/*
2678 	DebugFont *d = new DebugFont;
2679 	d->position = Vector(400,300);
2680 	d->setFontSize(16);
2681 	d->setText(msg);
2682 	d->alpha = 0;
2683 	d->alpha.interpolateTo(1, 0.75);
2684 	d->setLife(2);
2685 	d->setDecayRate(1);
2686 	d->followCamera = 1;
2687 	core->getTopStateData()->addRenderObject(d, LR_DEBUG_TEXT);
2688 	debugLog(msg);
2689 	*/
2690 }
2691 
onExitSaveSlotMenu()2692 void DSQ::onExitSaveSlotMenu()
2693 {
2694 	onPickedSaveSlot(0);
2695 }
2696 
onPickedSaveSlot(AquariaSaveSlot * slot)2697 bool DSQ::onPickedSaveSlot(AquariaSaveSlot *slot)
2698 {
2699 	if (slot == 0)
2700 	{
2701 		selectedSaveSlot = 0;
2702 		quitNestedMain();
2703 		return true;
2704 	}
2705 	else if ((saveSlotMode == SSM_LOAD && !slot->isEmpty()) || saveSlotMode == SSM_SAVE)
2706 	{
2707 		bool doit = false;
2708 
2709 		if (saveSlotMode == SSM_SAVE && !slot->isEmpty())
2710 		{
2711 			selectedSaveSlot = 0;
2712 			if (confirm("", "save"))
2713 				doit = true;
2714 		}
2715 		else
2716 		{
2717 			doit = true;
2718 		}
2719 
2720 		if (doit)
2721 		{
2722 			selectedSaveSlot = slot;
2723 			quitNestedMain();
2724 			return true;
2725 		}
2726 		else
2727 		{
2728 			slot->setFocus(true);
2729 		}
2730 	}
2731 
2732 	for (int i = 0; i < saveSlots.size(); i++)
2733 	{
2734 		saveSlots[i]->mbDown = false;
2735 	}
2736 
2737 	return false;
2738 }
2739 
nag(NagType type)2740 void DSQ::nag(NagType type)
2741 {
2742 	nagType = type;
2743 	core->enqueueJumpState("nag");
2744 }
2745 
doModSelect()2746 void DSQ::doModSelect()
2747 {
2748 	modIsSelected = false;
2749 
2750 	dsq->loadMods();
2751 
2752 	createModSelector();
2753 
2754 	resetTimer();
2755 
2756 	inModSelector = true;
2757 
2758 	main(-1);
2759 
2760 	clearModSelector();
2761 
2762 	if (modIsSelected)
2763 	{
2764 #ifdef AQUARIA_DEMO
2765 		nag(NAG_TOTITLE);
2766 #else
2767 		dsq->startSelectedMod();
2768 #endif
2769 	}
2770 
2771 	inModSelector = false;
2772 
2773 	modIsSelected = false;
2774 
2775 	resetTimer();
2776 }
2777 
createModSelector()2778 void DSQ::createModSelector()
2779 {
2780 	blackout = new Quad;
2781 	blackout->color = 0;
2782 	blackout->autoWidth = AUTO_VIRTUALWIDTH;
2783 	blackout->autoHeight = AUTO_VIRTUALHEIGHT;
2784 	blackout->followCamera = 1;
2785 	blackout->position = Vector(400,300);
2786 	blackout->alphaMod = 0.75;
2787 	blackout->alpha = 0;
2788 	blackout->alpha.interpolateTo(1, 0.2);
2789 	addRenderObject(blackout, LR_MENU);
2790 
2791 	modSelectorScr = new ModSelectorScreen();
2792 	modSelectorScr->position = Vector(400,300);
2793 	modSelectorScr->setWidth(getVirtualWidth()); // just to be sure
2794 	modSelectorScr->setHeight(getVirtualHeight());
2795 	modSelectorScr->autoWidth = AUTO_VIRTUALWIDTH;
2796 	modSelectorScr->autoHeight = AUTO_VIRTUALHEIGHT;
2797 	modSelectorScr->init();
2798 	addRenderObject(modSelectorScr, LR_MENU);
2799 }
2800 
modIsKnown(const std::string & name)2801 bool DSQ::modIsKnown(const std::string& name)
2802 {
2803 	std::string nlower = name;
2804 	stringToLower(nlower);
2805 
2806 	for(int i = 0; i < modEntries.size(); ++i)
2807 	{
2808 		std::string elower = modEntries[i].path;
2809 		stringToLower(elower);
2810 		if(nlower == elower)
2811 			return true;
2812 	}
2813 	return false;
2814 }
2815 
mountModPackage(const std::string & pkg)2816 bool DSQ::mountModPackage(const std::string& pkg)
2817 {
2818 #ifdef BBGE_BUILD_VFS
2819 	ttvfs::DirBase *vd = vfs.GetDir(pkg.c_str());
2820 	if (!vd)
2821 	{
2822 		// Load archive only if no such directory exists already (prevent loading multiple times)
2823 		vd = vfs.AddArchive(pkg.c_str());
2824 		if(!vd)
2825 		{
2826 			debugLog("Package: Unable to load " + pkg);
2827 			return false;
2828 		}
2829 	}
2830 	vfs.Mount(pkg.c_str(), mod.getBaseModPath().c_str());
2831 	debugLog("Package: Mounted " + pkg + " as archive in _mods");
2832 	return true;
2833 #else
2834 	debugLog("Package: Can't mount " + pkg + ", VFS support disabled");
2835 	return false;
2836 #endif
2837 }
2838 
2839 #ifdef BBGE_BUILD_VFS
_CloseSubdirCallback(ttvfs::DirBase * vd,void *)2840 static void _CloseSubdirCallback(ttvfs::DirBase *vd, void*)
2841 {
2842 	vd->close();
2843 }
2844 #endif
2845 
2846 // This just closes some file handles, nothing fancy
unloadMods()2847 void DSQ::unloadMods()
2848 {
2849 #ifdef BBGE_BUILD_VFS
2850 	ttvfs::DirView view;
2851 	if(vfs.FillDirView(mod.getBaseModPath().c_str(), view))
2852 		view.forEachDir(_CloseSubdirCallback);
2853 #endif
2854 }
2855 
applyParallaxUserSettings()2856 void DSQ::applyParallaxUserSettings()
2857 {
2858 	dsq->getRenderObjectLayer(LR_ELEMENTS10)->visible = dsq->user.video.parallaxOn0;
2859 	dsq->getRenderObjectLayer(LR_ELEMENTS11)->visible = dsq->user.video.parallaxOn1;
2860 	dsq->getRenderObjectLayer(LR_ELEMENTS12)->visible = dsq->user.video.parallaxOn2;
2861 }
2862 
clearModSelector()2863 void DSQ::clearModSelector()
2864 {
2865 	if (blackout)
2866 	{
2867 		blackout->setLife(1);
2868 		blackout->setDecayRate(2);
2869 		blackout->fadeAlphaWithLife = 1;
2870 		blackout = 0;
2871 	}
2872 
2873 	if(modSelectorScr)
2874 	{
2875 		modSelectorScr->close();
2876 		modSelectorScr->setLife(1);
2877 		modSelectorScr->setDecayRate(2);
2878 		modSelectorScr->fadeAlphaWithLife = 1;
2879 		modSelectorScr = 0;
2880 	}
2881 
2882 	// This just closes some file handles, nothing fancy
2883 	unloadMods();
2884 
2885 	clearMenu();
2886 }
2887 
2888 
2889 
updateSaveSlotPageCount()2890 void DSQ::updateSaveSlotPageCount()
2891 {
2892 	std::ostringstream os;
2893 	os << dsq->continuity.stringBank.get(2006) << " " << user.data.savePage+1 << "/" << maxPages+1;
2894 	saveSlotPageCount->setText(os.str());
2895 }
2896 
2897 
createSaveSlots(SaveSlotMode ssm)2898 void DSQ::createSaveSlots(SaveSlotMode ssm)
2899 {
2900 	if (!saveSlots.empty())
2901 	{
2902 		errorLog("save slots weren't cleared");
2903 	}
2904 	if (!menu.empty())
2905 	{
2906 		errorLog ("menu wasn't cleared");
2907 	}
2908 	menu.resize(5);
2909 
2910 	float t = 0.3;
2911 
2912 
2913 	blackout = new Quad;
2914 	blackout->color = 0;
2915 	blackout->autoWidth = AUTO_VIRTUALWIDTH;
2916 	blackout->autoHeight = AUTO_VIRTUALHEIGHT;
2917 	blackout->followCamera = 1;
2918 	blackout->position = Vector(400,300);
2919 	blackout->alphaMod = 0.75;
2920 	blackout->alpha = 0;
2921 	blackout->alpha.interpolateTo(1, 0.5);
2922 	addRenderObject(blackout, LR_MENU);
2923 
2924 
2925 	menu[1] = new Quad("gui/save-menu", Vector(400,300));
2926 	savesz = Vector(750.0f/1024.0f, 750.0f/1024.0f);
2927 	menu[1]->alpha = 0;
2928 	menu[1]->alpha.interpolateTo(1, t);
2929 	menu[1]->scale = savesz * 0.5f;
2930 	menu[1]->scale.interpolateTo(savesz, t);
2931 	menu[1]->followCamera = 1;
2932 	addRenderObject(menu[1], LR_MENU);
2933 
2934 	core->sound->playSfx("menu-open");
2935 
2936 	watch(t);
2937 
2938 	saveSlotPageCount = new BitmapText(&dsq->smallFont);
2939 	saveSlotPageCount->followCamera = 1;
2940 	saveSlotPageCount->setAlign(ALIGN_LEFT);
2941 	saveSlotPageCount->position = Vector(590, 300);
2942 	addRenderObject(saveSlotPageCount, LR_MENU);
2943 	updateSaveSlotPageCount();
2944 
2945 
2946 	cancel = new AquariaMenuItem();
2947 	//menu[0]->setLabel("Cancel");
2948 	cancel->useGlow("glow", 200, 50);
2949 	cancel->event.set(MakeFunctionEvent(DSQ,onExitSaveSlotMenu));
2950 	cancel->position = Vector(665, 545); // 670
2951 	addRenderObject(cancel, LR_MENU);
2952 
2953 	menu[0] = cancel;
2954 
2955 	/*
2956 	menu[1] = new Quad("Cancel", Vector(750,580));
2957 	menu[1]->followCamera = 1;
2958 	addRenderObject(menu[1], LR_MENU);
2959 	*/
2960 
2961 	arrowUp = new AquariaMenuItem();
2962 	arrowUp->useQuad("gui/arrow-left");
2963 	arrowUp->useGlow("glow", 100, 50);
2964 	arrowUp->useSound("click");
2965 	arrowUp->event.set(MakeFunctionEvent(DSQ, prevSaveSlotPage));
2966 	arrowUp->rotation.z = 90;
2967 	arrowUp->scale = Vector(0.75, 0.75);
2968 	arrowUp->position = Vector(620, 200);
2969 	addRenderObject(arrowUp, LR_MENU);
2970 
2971 	menu[2] = arrowUp;
2972 
2973 	arrowDown = new AquariaMenuItem();
2974 	arrowDown->useQuad("gui/arrow-right");
2975 	arrowDown->useSound("click");
2976 	arrowDown->useGlow("glow", 100, 50);
2977 	arrowDown->scale = Vector(0.75, 0.75);
2978 	arrowDown->event.set(MakeFunctionEvent(DSQ, nextSaveSlotPage));
2979 	arrowDown->rotation.z = 90;
2980 	arrowDown->position = Vector(620, 400);
2981 	addRenderObject(arrowDown, LR_MENU);
2982 
2983 	if (dsq->game->miniMapRender)
2984 		dsq->game->miniMapRender->slide(1);
2985 
2986 	menu[3] = arrowDown;
2987 
2988 	BitmapText *txt = new BitmapText(&dsq->font);
2989 	if (ssm == SSM_LOAD)
2990 		txt->setText(continuity.stringBank.get(2001));
2991 	else
2992 		txt->setText(continuity.stringBank.get(2000));
2993 	txt->position = Vector(230, 68);
2994 	txt->followCamera = 1;
2995 	addRenderObject(txt, LR_MENU);
2996 
2997 	menu[4] = txt;
2998 
2999 	createSaveSlotPage();
3000 
3001 	saveSlots[0]->setFocus(true);
3002 }
3003 
title(bool fade)3004 void DSQ::title(bool fade)
3005 {
3006 	core->settings.runInBackground = false;
3007 	recentSaveSlot = -1;
3008 
3009 	dsq->overlay->color = 0;
3010 	dsq->overlay->alpha.interpolateTo(1, 1);
3011 
3012 	if (fade)
3013 	{
3014 		dsq->sound->fadeMusic(SFT_OUT, 1);
3015 	}
3016 
3017 	main(1);
3018 
3019 	resetTimer();
3020 
3021 	if (fade)
3022 		dsq->sound->stopMusic();
3023 
3024 	user.save();
3025 
3026 	if (mod.isActive())
3027 	{
3028 		mod.shutdown();
3029 	}
3030 
3031 	// Will be re-loaded on demand
3032 	unloadMods();
3033 
3034 	// VERY important
3035 	dsq->continuity.reset();
3036 
3037 	dsq->game->transitionToScene("Title");
3038 }
3039 
createSaveSlotPage()3040 void DSQ::createSaveSlotPage()
3041 {
3042 	for (int i = 0; i < saveSlots.size(); i++)
3043 	{
3044 		saveSlots[i]->safeKill();
3045 	}
3046 
3047 	saveSlots.resize(saveSlotPageSize);
3048 	for (int i = 0; i < saveSlots.size(); i++)
3049 	{
3050 		saveSlots[i] = new AquariaSaveSlot(i + user.data.savePage *  saveSlotPageSize);
3051 		saveSlots[i]->followCamera = 1;
3052 		saveSlots[i]->position = Vector(409,193+i*90);
3053 		if (i != 1)
3054 			saveSlots[i]->position.y ++;
3055 
3056 		if (i == 1 || i == 3)
3057 			saveSlots[i]->position.y -= 0.5f;
3058 
3059 		addRenderObject(saveSlots[i], LR_FILEMENU);
3060 	}
3061 
3062 
3063 	if (inputMode == INPUT_JOYSTICK)
3064 	{
3065 		saveSlots[0]->setDirMove(DIR_RIGHT, arrowUp);
3066 		saveSlots[1]->setDirMove(DIR_RIGHT, arrowUp);
3067 		saveSlots[2]->setDirMove(DIR_RIGHT, arrowDown);
3068 		saveSlots[3]->setDirMove(DIR_RIGHT, cancel);
3069 		arrowDown->setDirMove(DIR_DOWN, cancel);
3070 		cancel->setDirMove(DIR_UP, arrowDown);
3071 		cancel->setDirMove(DIR_LEFT, saveSlots[3]);
3072 	}
3073 }
3074 
nextSaveSlotPage()3075 void DSQ::nextSaveSlotPage()
3076 {
3077 	if (saveSlots.empty()) return;
3078 
3079 	user.data.savePage++;
3080 	if (user.data.savePage > maxPages)
3081 		user.data.savePage = 0;
3082 	createSaveSlotPage();
3083 
3084 	updateSaveSlotPageCount();
3085 }
3086 
prevSaveSlotPage()3087 void DSQ::prevSaveSlotPage()
3088 {
3089 	if (saveSlots.empty()) return;
3090 
3091 	user.data.savePage--;
3092 	if (user.data.savePage < 0)
3093 		user.data.savePage = maxPages;
3094 	createSaveSlotPage();
3095 
3096 	updateSaveSlotPageCount();
3097 }
3098 
hideSaveSlotCrap()3099 void DSQ::hideSaveSlotCrap()
3100 {
3101 	clearMenu();
3102 
3103 	if (blackout)
3104 		blackout->alpha = 0;
3105 
3106 	if (saveSlotPageCount)
3107 		saveSlotPageCount->alpha = 0;
3108 }
3109 
clearSaveSlots(bool trans)3110 void DSQ::clearSaveSlots(bool trans)
3111 {
3112 	if (trans)
3113 	{
3114 		core->sound->playSfx("menu-close");
3115 	}
3116 	float t = 0.3;
3117 	if (blackout)
3118 	{
3119 		if (!trans)
3120 		{
3121 			blackout->setLife(1);
3122 			blackout->setDecayRate(10);
3123 			if (blackout->alpha.x > 0)
3124 				blackout->fadeAlphaWithLife = 1;
3125 		}
3126 		else
3127 		{
3128 			blackout->setLife(1);
3129 			blackout->setDecayRate(1);
3130 			if (blackout->alpha.x > 0)
3131 				blackout->fadeAlphaWithLife = 1;
3132 		}
3133 	}
3134 	if (saveSlotPageCount)
3135 	{
3136 		saveSlotPageCount->setLife(1);
3137 		saveSlotPageCount->setDecayRate(10);
3138 		if (saveSlotPageCount->alpha.x > 0)
3139 			saveSlotPageCount->fadeAlphaWithLife = 1;
3140 	}
3141 
3142 	for (int i = 0; i < saveSlots.size(); i++)
3143 	{
3144 		saveSlots[i]->close(trans);
3145 	}
3146 
3147 	saveSlots.clear();
3148 
3149 	//watch(0.25);
3150 
3151 	if (trans)
3152 	{
3153 		disableMiniMapOnNoInput = false;
3154 
3155 		for (int i = 0; i < menu.size(); i++)
3156 		{
3157 			if (i != 1)
3158 			{
3159 				menu[i]->alpha = 0;
3160 				//menu[i]->alpha.interpolateTo(0, 0.01);
3161 			}
3162 		}
3163 		if (menu.size() >= 2)
3164 		{
3165 			menu[1]->scale.interpolateTo(savesz*0.5f, t);
3166 			menu[1]->alpha.interpolateTo(0, t);
3167 			watch(t);
3168 		}
3169 
3170 		disableMiniMapOnNoInput = true;
3171 	}
3172 	clearMenu();
3173 	//watch(0.5);
3174 
3175 	if (dsq->game->miniMapRender)
3176 		dsq->game->miniMapRender->slide(0);
3177 }
3178 
hideSaveSlots()3179 void DSQ::hideSaveSlots()
3180 {
3181 	for (int i = 0; i < saveSlots.size(); i++)
3182 	{
3183 		saveSlots[i]->hide();
3184 	}
3185 }
3186 
transitionSaveSlots()3187 void DSQ::transitionSaveSlots()
3188 {
3189 	hideSaveSlotCrap();
3190 
3191 	for (int i = 0; i < saveSlots.size(); i++)
3192 	{
3193 		saveSlots[i]->transition();
3194 	}
3195 }
3196 
doSaveSlotMenu(SaveSlotMode ssm,const Vector & position)3197 void DSQ::doSaveSlotMenu(SaveSlotMode ssm, const Vector &position)
3198 {
3199 	int scrShotWidth = 0, scrShotHeight = 0;
3200 	unsigned char *scrShotData = 0;
3201 
3202 	if (ssm == SSM_SAVE && user.video.saveSlotScreens)
3203 	{
3204 		prepScreen(1);
3205 
3206 		int renderWidth = getWindowWidth(), renderHeight = getWindowHeight();
3207 		int i = 2;
3208 		while (1 << i < renderHeight)
3209 		{
3210 			i++;
3211 		}
3212 		scrShotWidth = scrShotHeight = 1 << (i-1);
3213 		int x = renderWidth/2  - scrShotWidth/2;
3214 		int y = renderHeight/2 - scrShotHeight/2;
3215 
3216 		glPushAttrib(GL_VIEWPORT_BIT);
3217 		glViewport(0, 0, renderWidth, renderHeight);
3218 		clearBuffers();
3219 		render();
3220 		scrShotData = core->grabScreenshot(x, y, scrShotWidth, scrShotHeight);
3221 		glPopAttrib();
3222 		showBuffer();
3223 
3224 		prepScreen(0);
3225 	}
3226 
3227 	saveSlotMode = SSM_NONE;
3228 
3229 	createSaveSlots(ssm);
3230 	const int firstSaveSlot = user.data.savePage * saveSlotPageSize;
3231 	if (user.data.saveSlot >= firstSaveSlot && user.data.saveSlot < firstSaveSlot + saveSlots.size())
3232 	{
3233 		selectedSaveSlot = saveSlots[user.data.saveSlot - firstSaveSlot];
3234 		selectedSaveSlot->setFocus(true);
3235 	}
3236 	else
3237 	{
3238 		selectedSaveSlot = 0;
3239 	}
3240 
3241 	saveSlotMode = ssm;
3242 
3243 	//core->globalScale.interpolateTo(Vector(1, 1), 0.5);
3244 
3245 	resetTimer();
3246 	core->main(-1);
3247 
3248 
3249 
3250 	if (selectedSaveSlot == 0)
3251 	{
3252 		if (saveSlotMode == SSM_SAVE)
3253 		{
3254 			clearSaveSlots(true);
3255 		}
3256 	}
3257 	else
3258 	{
3259 		// Drop focus early so it doesn't see joystick movement and
3260 		// try to select a destroyed save slot (and thus crash).
3261 		selectedSaveSlot->setFocus(false);
3262 		recentSaveSlot = selectedSaveSlot->getSlotIndex();
3263 		user.data.saveSlot = recentSaveSlot;
3264 		if (saveSlotMode == SSM_SAVE)
3265 		{
3266 			continuity.saveFile(selectedSaveSlot->getSlotIndex(), position, scrShotData, scrShotWidth, scrShotHeight);
3267 			if (user.video.saveSlotScreens && scrShotData != 0)
3268 			{
3269 				std::ostringstream os;
3270 				os << dsq->getSaveDirectory() << "/screen-" << numToZeroString(selectedSaveSlot->getSlotIndex(), 4) << ".zga";
3271 
3272 				// Cut off top and bottom to get a 4:3 aspect ratio.
3273 				int adjHeight = (scrShotWidth * 3.0f) / 4.0f;
3274 				int imageDataSize = scrShotWidth * scrShotHeight * 4;
3275 				int adjImageSize = scrShotWidth * adjHeight * 4;
3276 				int adjOffset = scrShotWidth * ((scrShotHeight-adjHeight)/2) * 4;
3277 				memmove(scrShotData, scrShotData + adjOffset, adjImageSize);
3278 				memset(scrShotData + adjImageSize, 0, imageDataSize - adjImageSize);
3279 				zgaSave(os.str().c_str(), scrShotWidth, scrShotHeight, 32, scrShotData);
3280 				scrShotData = 0;  // deleted by tgaSave()
3281 			}
3282 
3283 			PlaySfx sfx;
3284 			sfx.name = "saved";
3285 			sfx.vol = 0.55;
3286 			dsq->sound->playSfx(sfx);
3287 			confirm("", "saved", 1);
3288 
3289 			clearSaveSlots(true);
3290 		}
3291 		else if (saveSlotMode == SSM_LOAD)
3292 		{
3293 			continuity.loadFile(selectedSaveSlot->getSlotIndex());
3294 			dsq->game->transitionToScene(dsq->game->sceneToLoad);
3295 		}
3296 		// when gameover hits, load up this instead of that.
3297 	}
3298 
3299 	resetTimer();
3300 
3301 	delete[] scrShotData;
3302 	saveSlotMode = SSM_NONE;
3303 
3304 }
3305 
getEntityFlagName(Entity * e)3306 std::string DSQ::getEntityFlagName(Entity *e)
3307 {
3308 	if (!dsq->game) return "";
3309 	std::ostringstream os;
3310 	os << dsq->game->sceneName << e->startPos.x << e->startPos.y;
3311 	return os.str();
3312 }
3313 
doAlphabetInputKey(int d,char c,char map[],std::string * text,char upper=0)3314 void doAlphabetInputKey(int d, char c, char map[], std::string *text, char upper=0)
3315 {
3316 	if (core->getKeyState(d) && !map[d])
3317 	{
3318 		char usec = c;
3319 		if (upper != 0 && (core->getKeyState(KEY_LSHIFT) || core->getKeyState(KEY_RSHIFT)))
3320 		{
3321 			usec = upper;
3322 		}
3323 		*text += usec;
3324 		map[d] = 1;
3325 	}
3326 	else if (!core->getKeyState(d) && map[d])
3327 	{
3328 		map[d] = 0;
3329 	}
3330 }
3331 
generateCollisionMask(RenderObject * r)3332 void DSQ::generateCollisionMask(RenderObject *r)
3333 {
3334 	Quad *q = dynamic_cast<Quad*>(r);
3335 	if (q)
3336 		game->generateCollisionMask(q);
3337 }
3338 
onConfirmYes()3339 void DSQ::onConfirmYes()
3340 {
3341 	dsq->confirmDone = 1;
3342 }
3343 
onConfirmNo()3344 void DSQ::onConfirmNo()
3345 {
3346 	dsq->confirmDone = 2;
3347 }
3348 
confirm(const std::string & text,const std::string & image,bool ok,float countdown)3349 bool DSQ::confirm(const std::string &text, const std::string &image, bool ok, float countdown)
3350 {
3351 	const float t = 0.3;
3352 
3353 	sound->playSfx("menu-open");
3354 
3355 	confirmDone = 0;
3356 
3357 	std::string imageName = "gui/confirm-bg";
3358 	if (!image.empty())
3359 	{
3360 		imageName += "-" + image;
3361 	}
3362 
3363 	Quad *bgLabel = new Quad(imageName, Vector(400,300));
3364 	bgLabel->followCamera = 1;
3365 	bgLabel->alpha = 0;
3366 	bgLabel->alpha.interpolateTo(1, t);
3367 	//bgLabel->setWidthHeight(512*0.9f, 256*0.9f);
3368 	bgLabel->scale = Vector(0.5, 0.5);
3369 	bgLabel->scale.interpolateTo(Vector(1,1), t);
3370 	addRenderObject(bgLabel, LR_CONFIRM);
3371 
3372 	const int GUILEVEL_CONFIRM = 200;
3373 
3374 	AquariaGuiElement::currentGuiInputLevel = GUILEVEL_CONFIRM;
3375 
3376 	dsq->main(t);
3377 
3378 	float t2 = 0.05;
3379 
3380 	/*
3381 	Quad *yes = new Quad("gui/yes", Vector(350, 400));
3382 	yes->followCamera = 1;
3383 	yes->alpha = 0;
3384 	yes->alpha.interpolateTo(1, t2);
3385 	addRenderObject(yes, LR_CONFIRM);
3386 
3387 	Quad *no = new Quad("gui/no", Vector(450, 400));
3388 	no->followCamera = 1;
3389 	no->alpha = 0;
3390 	no->alpha.interpolateTo(1, t2);
3391 	addRenderObject(no, LR_CONFIRM);
3392 	*/
3393 
3394 	AquariaMenuItem *yes=0;
3395 	AquariaMenuItem *no=0;
3396 
3397 	if (ok)
3398 	{
3399 		yes = new AquariaMenuItem();
3400 		yes->useQuad("gui/ok");
3401 		yes->useGlow("glow", 64, 50);
3402 		yes->event.set(MakeFunctionEvent(DSQ,onConfirmYes));
3403 
3404 		yes->position = Vector(400, 340);
3405 		addRenderObject(yes, LR_CONFIRM);
3406 
3407 		yes->setFocus(true);
3408 
3409 		yes->setCanDirMove(false);
3410 
3411 		yes->guiInputLevel = GUILEVEL_CONFIRM;
3412 	}
3413 	else
3414 	{
3415 		yes = new AquariaMenuItem();
3416 		yes->useQuad("yes");
3417 		yes->useGlow("glow", 64, 50);
3418 		yes->event.set(MakeFunctionEvent(DSQ,onConfirmYes));
3419 
3420 		yes->position = Vector(330, 340);
3421 		addRenderObject(yes, LR_CONFIRM);
3422 
3423 		yes->guiInputLevel = GUILEVEL_CONFIRM;
3424 
3425 		no = new AquariaMenuItem();
3426 		no->useQuad("no");
3427 		no->useGlow("glow", 64, 50);
3428 		no->event.set(MakeFunctionEvent(DSQ,onConfirmNo));
3429 
3430 		no->position = Vector(470, 340);
3431 		addRenderObject(no, LR_CONFIRM);
3432 
3433 		no->guiInputLevel = GUILEVEL_CONFIRM;
3434 
3435 		no->setFocus(true);
3436 
3437 		no->setDirMove(DIR_LEFT, yes);
3438 
3439 		no->setDirMove(DIR_UP, no);
3440 		no->setDirMove(DIR_DOWN, no);
3441 		no->setDirMove(DIR_RIGHT, no);
3442 
3443 		yes->setDirMove(DIR_RIGHT, no);
3444 
3445 		yes->setDirMove(DIR_UP, yes);
3446 		yes->setDirMove(DIR_DOWN, yes);
3447 		yes->setDirMove(DIR_LEFT, yes);
3448 	}
3449 
3450 	BitmapText *txt = new BitmapText(&dsq->smallFont);
3451 	txt->followCamera = 1;
3452 	txt->position = Vector(400,250);
3453 	txt->setText(text);
3454 	txt->alpha = 0;
3455 	txt->scale = Vector(0.9, 0.9);
3456 	txt->alpha.interpolateTo(1, t2);
3457 	addRenderObject(txt, LR_CONFIRM);
3458 
3459 	dsq->main(t2);
3460 
3461 	while (!confirmDone)
3462 	{
3463 		dsq->main(FRAME_TIME);
3464 		if (countdown > 0) {
3465 			countdown -= FRAME_TIME;
3466 			if (countdown < 0)
3467 				break;
3468 		}
3469 	}
3470 
3471 	sound->playSfx("menu-close");
3472 
3473 	txt->alpha.interpolateTo(0, t2);
3474 	if (yes)	yes->alpha.interpolateTo(0, t2);
3475 	if (no)		no->alpha.interpolateTo(0, t2);
3476 	dsq->main(t2);
3477 
3478 	bgLabel->alpha.interpolateTo(0, t);
3479 	bgLabel->scale.interpolateTo(Vector(0.5, 0.5), t);
3480 	dsq->main(t);
3481 
3482 	bgLabel->safeKill();
3483 	txt->safeKill();
3484 	if (yes)
3485 	{
3486 		yes->setFocus(false);
3487 		yes->safeKill();
3488 	}
3489 	if (no)
3490 	{
3491 		no->setFocus(false);
3492 		no->safeKill();
3493 	}
3494 
3495 	bool ret = (confirmDone == 1);
3496 
3497 	if (countdown < 0)
3498 		ret = false;
3499 
3500 	AquariaGuiElement::currentGuiInputLevel = 0;
3501 
3502 	return ret;
3503 }
3504 
getUserInputString(std::string labelText,std::string t,bool allowNonLowerCase)3505 std::string DSQ::getUserInputString(std::string labelText, std::string t, bool allowNonLowerCase)
3506 {
3507 	float trans = 0.1;
3508 
3509 	bool pauseState = dsq->game->isPaused();
3510 
3511 	dsq->game->togglePause(true);
3512 
3513 	sound->playSfx("Menu-Open");
3514 
3515 	RoundedRect *bg = new RoundedRect;
3516 	bg->setWidthHeight(790, 64, 10);
3517 	bg->position = Vector(400,300);
3518 	bg->followCamera = 1;
3519 	bg->alpha = 0;
3520 	addRenderObject(bg, LR_DEBUG_TEXT);
3521 
3522 	/*
3523 	DebugFont *label = new DebugFont();
3524 	label->setFontSize(10);
3525 	label->setText(labelText);
3526 	label->position = Vector(20,250 - label->getNumLines()*10);
3527 	label->followCamera = 1;
3528 	label->alpha = 0;
3529 	label->alpha.interpolateTo(1, trans);
3530 	*/
3531 
3532 	TTFText *label = new TTFText(&dsq->fontArialSmall);
3533 	label->setText(labelText);
3534 	label->position = Vector(-400 + 20, -12); //- label->getNumLines()*10
3535 	bg->addChild(label, PM_POINTER);
3536 
3537 	TTFText *inputText = new TTFText(&dsq->fontArialBig);
3538 	//inputText->setFontSize(14);
3539 	inputText->position = Vector(-400 + 20,8+8);
3540 	bg->addChild(inputText, PM_POINTER);
3541 	//addRenderObject(inputText, LR_DEBUG_TEXT);
3542 
3543 	bg->show();
3544 	main(trans);
3545 
3546 
3547 	std::string text = t;
3548 	char map[256];
3549 	for (int i = 0; i < 256; i++)
3550 		map[i] = 0;
3551 	bool delDown = false;
3552 	bool escDown = false;
3553 
3554 	float dt = 1.0f/60.0f;
3555 	float blinkTimer = 0;
3556 	bool blink = false;
3557 
3558 	while (1)
3559 	{
3560 		if (blink)
3561 		{
3562 			text.resize(text.size()-1);
3563 			inputText->setText(text);
3564 		}
3565 		if (inputText->getActualWidth() < 800-60)
3566 		{
3567 			doAlphabetInputKey(KEY_A, 'a', (char*)&map, &text, 'A');
3568 			doAlphabetInputKey(KEY_B, 'b', (char*)&map, &text, 'B');
3569 			doAlphabetInputKey(KEY_C, 'c', (char*)&map, &text, 'C');
3570 			doAlphabetInputKey(KEY_D, 'd', (char*)&map, &text, 'D');
3571 			doAlphabetInputKey(KEY_E, 'e', (char*)&map, &text, 'E');
3572 			doAlphabetInputKey(KEY_F, 'f', (char*)&map, &text, 'F');
3573 			doAlphabetInputKey(KEY_G, 'g', (char*)&map, &text, 'G');
3574 			doAlphabetInputKey(KEY_H, 'h', (char*)&map, &text, 'H');
3575 			doAlphabetInputKey(KEY_I, 'i', (char*)&map, &text, 'I');
3576 			doAlphabetInputKey(KEY_J, 'j', (char*)&map, &text, 'J');
3577 			doAlphabetInputKey(KEY_K, 'k', (char*)&map, &text, 'K');
3578 			doAlphabetInputKey(KEY_L, 'l', (char*)&map, &text, 'L');
3579 			doAlphabetInputKey(KEY_M, 'm', (char*)&map, &text, 'M');
3580 			doAlphabetInputKey(KEY_N, 'n', (char*)&map, &text, 'N');
3581 			doAlphabetInputKey(KEY_O, 'o', (char*)&map, &text, 'O');
3582 			doAlphabetInputKey(KEY_P, 'p', (char*)&map, &text, 'P');
3583 			doAlphabetInputKey(KEY_Q, 'q', (char*)&map, &text, 'Q');
3584 			doAlphabetInputKey(KEY_R, 'r', (char*)&map, &text, 'R');
3585 			doAlphabetInputKey(KEY_S, 's', (char*)&map, &text, 'S');
3586 			doAlphabetInputKey(KEY_T, 't', (char*)&map, &text, 'T');
3587 			doAlphabetInputKey(KEY_U, 'u', (char*)&map, &text, 'U');
3588 			doAlphabetInputKey(KEY_V, 'v', (char*)&map, &text, 'V');
3589 			doAlphabetInputKey(KEY_W, 'w', (char*)&map, &text, 'W');
3590 			doAlphabetInputKey(KEY_X, 'x', (char*)&map, &text, 'X');
3591 			doAlphabetInputKey(KEY_Y, 'y', (char*)&map, &text, 'Y');
3592 			doAlphabetInputKey(KEY_Z, 'z', (char*)&map, &text, 'Z');
3593 			doAlphabetInputKey(KEY_1, '1', (char*)&map, &text);
3594 			doAlphabetInputKey(KEY_2, '2', (char*)&map, &text);
3595 			doAlphabetInputKey(KEY_3, '3', (char*)&map, &text);
3596 			doAlphabetInputKey(KEY_4, '4', (char*)&map, &text);
3597 			doAlphabetInputKey(KEY_5, '5', (char*)&map, &text);
3598 			doAlphabetInputKey(KEY_6, '6', (char*)&map, &text);
3599 			doAlphabetInputKey(KEY_7, '7', (char*)&map, &text);
3600 			doAlphabetInputKey(KEY_8, '8', (char*)&map, &text);
3601 			doAlphabetInputKey(KEY_9, '9', (char*)&map, &text);
3602 			doAlphabetInputKey(KEY_0, '0', (char*)&map, &text);
3603 
3604 			doAlphabetInputKey(KEY_PERIOD, '.', (char*)&map, &text);
3605 			doAlphabetInputKey(KEY_SPACE, ' ', (char*)&map, &text);
3606 			doAlphabetInputKey(KEY_MINUS, '-', (char*)&map, &text, '_');
3607 
3608 			doAlphabetInputKey(KEY_TILDE, '~', (char*)&map, &text, '~');
3609 		}
3610 
3611 		if (core->getKeyState(KEY_BACKSPACE))
3612 		{
3613 			if (!delDown)
3614 			{
3615 				if (!text.empty())
3616 				{
3617 					text.resize(text.size()-1);
3618 				}
3619 			}
3620 			delDown = true;
3621 		}
3622 		else
3623 		{
3624 			delDown = false;
3625 		}
3626 
3627 		blinkTimer += dt;
3628 		if (blinkTimer > 0.2f)
3629 		{
3630 			blink = !blink;
3631 			blinkTimer = 0;
3632 		}
3633 
3634 		if (blink)
3635 		{
3636 			text += "|";
3637 		}
3638 
3639 
3640 
3641 		if (core->getKeyState(KEY_RETURN))
3642 			break;
3643 
3644 		if (!escDown && core->getKeyState(KEY_ESCAPE))
3645 			escDown = true;
3646 		else if (escDown && !core->getKeyState(KEY_ESCAPE))
3647 		{
3648 			escDown = false;
3649 			text = t;
3650 			break;
3651 		}
3652 		inputText->setText(text);
3653 		core->main(dt);
3654 	}
3655 
3656 	if (blink && !text.empty() && (text[text.size()-1] == '|'))
3657 		text.resize(text.size()-1);
3658 
3659 	sound->playSfx("Menu-Close");
3660 
3661 	/*
3662 	inputText->offset.interpolateTo(Vector(800, 0), 0.2);
3663 	label->offset.interpolateTo(Vector(800, 0), 0.2);
3664 	bg->offset.interpolateTo(Vector(800, 0), 0.2);
3665 	*/
3666 	bg->hide();
3667 
3668 	main(0.2);
3669 
3670 	inputText->alpha = 0;
3671 	label->alpha = 0;
3672 	inputText->safeKill();
3673 	label->safeKill();
3674 	bg->alpha = 0;
3675 	bg->safeKill();
3676 
3677 	dsq->game->togglePause(pauseState);
3678 
3679 	if (!allowNonLowerCase)
3680 		stringToLower(text);
3681 
3682 	debugLog("getUserInputString returned: " + text);
3683 
3684 	return text;
3685 }
3686 
stopVoice()3687 void DSQ::stopVoice()
3688 {
3689 	sound->stopVoice();
3690 	subtitlePlayer.end();
3691 }
3692 
playedVoice(const std::string & file)3693 bool DSQ::playedVoice(const std::string &file)
3694 {
3695 	std::string f = file;
3696 	stringToUpper(f);
3697 	for (int i = 0; i < dsq->continuity.voiceOversPlayed.size(); i++)
3698 	{
3699 		if (f == dsq->continuity.voiceOversPlayed[i])
3700 		{
3701 			return true;
3702 		}
3703 	}
3704 	return false;
3705 }
3706 
voiceOnce(const std::string & file)3707 void DSQ::voiceOnce(const std::string &file)
3708 {
3709 	std::string f = file;
3710 	stringToUpper(f);
3711 	if (!playedVoice(f))
3712 	{
3713 		voice(file);
3714 	}
3715 }
3716 
3717 // This is a pretty "dangerous" function
3718 // it will kill the current voice over and all pending voice overs
3719 // recommended only in situations where overriding the voice is acceptable
3720 // i.e. song cave door (1st songdoor)
voiceInterupt(const std::string & f)3721 void DSQ::voiceInterupt(const std::string &f)
3722 {
3723 	sound->playVoice(f, SVT_INTERRUPT);
3724 	/*
3725 	voxQueue.clear();
3726 	if (streamingVoice)
3727 	{
3728 		streamingVoice = false;
3729 		if (stream)
3730 		{
3731 			BASS_ChannelSlideAttributes(stream, -1, -2, -101, 500);
3732 			stream = 0;
3733 		}
3734 	}
3735 	voice(f);
3736 	*/
3737 }
3738 
3739 /*
3740 void DSQ::updateVoiceVolume()
3741 {
3742 	if (streamingVoice)
3743 	{
3744 		BASS_ChannelSlideAttributes(stream, -1, user.audio.voxvol*100.0f, -101, 100);
3745 	}
3746 }
3747 */
3748 
onPlayVoice()3749 void DSQ::onPlayVoice()
3750 {
3751 	/*
3752 	if (user.audio.subtitles)
3753 	{
3754 		std::string fn = "scripts/vox/" + sound->lastVoice + ".txt";
3755 		std::ifstream inf(fn.c_str());
3756 		if (inf.is_open())
3757 		{
3758 			std::string dia;
3759 			std::getline(inf, dia);
3760 
3761 			if (!dia.empty())
3762 				hint(dia);
3763 		}
3764 		inf.close();
3765 	}
3766 	*/
3767 }
3768 
onStopVoice()3769 void DSQ::onStopVoice()
3770 {
3771 	subtitlePlayer.end();
3772 	/*
3773 	if (user.audio.subtitles)
3774 	{
3775 		hint("");
3776 	}
3777 	*/
3778 }
3779 
voice(const std::string & f,float volMod)3780 void DSQ::voice(const std::string &f, float volMod)
3781 {
3782 	debugLog("Voice: " + f);
3783 	std::string file = f;
3784 	stringToUpper(file);
3785 
3786 	if (!playedVoice(file))
3787 		dsq->continuity.voiceOversPlayed.push_back(file);
3788 
3789 	sound->playVoice(file, SVT_QUEUE, volMod);
3790 }
3791 
onPlayedVoice(const std::string & name)3792 void DSQ::onPlayedVoice(const std::string &name)
3793 {
3794 	Core::onPlayedVoice(name);
3795 
3796 	if (user.audio.subtitles)
3797 		subtitlePlayer.go(name);
3798 }
3799 
getFirstEntity()3800 Entity *DSQ::getFirstEntity()
3801 {
3802 	iter = &entities[0];
3803 	return getNextEntity();
3804 }
3805 
getNextEntity()3806 Entity *DSQ::getNextEntity()
3807 {
3808 	if (*iter == 0)
3809 		return 0;
3810 	return *(iter++);
3811 }
3812 
getUserInputDirection(std::string labelText)3813 Vector DSQ::getUserInputDirection(std::string labelText)
3814 {
3815 	BitmapText *label = new BitmapText(&dsq->font);
3816 	label->setFontSize(16);
3817 	label->position = Vector(400,200);
3818 	label->followCamera = 1;
3819 	label->setText(labelText);
3820 	addRenderObject(label, LR_HUD);
3821 
3822 	while (core->getKeyState(KEY_RETURN))
3823 	{
3824 		core->main(1.0f/30.0f);
3825 	}
3826 	Vector v;
3827 	while (1)
3828 	{
3829 		v.x = v.y = 0;
3830 		if (core->getKeyState(KEY_LEFT))		v.x = -1;
3831 		if (core->getKeyState(KEY_RIGHT))		v.x = 1;
3832 		if (core->getKeyState(KEY_UP))			v.y = -1;
3833 		if (core->getKeyState(KEY_DOWN))		v.y = 1;
3834 		if (core->getKeyState(KEY_RETURN))
3835 			break;
3836 		core->main(1.0f/30.0f);
3837 	}
3838 	label->alpha = 0;
3839 	label->safeKill();
3840 	return v;
3841 }
3842 
getDialogueFilename(const std::string & f)3843 std::string DSQ::getDialogueFilename(const std::string &f)
3844 {
3845 	return "dialogue/" + languagePack + "/" + f + ".txt";
3846 }
3847 
jumpToSection(InStream & inFile,const std::string & section)3848 void DSQ::jumpToSection(InStream &inFile, const std::string &section)
3849 {
3850 	if (section.empty()) return;
3851 	std::string file = dsq->getDialogueFilename(dialogueFile);
3852 	if (!exists(file))
3853 	{
3854 		debugLog("Could not find dialogue [" + file + "]");
3855 		return;
3856 	}
3857 	inFile.open(core->adjustFilenameCase(file).c_str());
3858 	std::string s;
3859 	while (std::getline(inFile, s))
3860 	{
3861 		if (!s.empty())
3862 		{
3863 			if (s.find("[")!=std::string::npos && s.find(section) != std::string::npos)
3864 			{
3865 				return;
3866 			}
3867 		}
3868 	}
3869 	debugLog("could not find section [" + section + "]");
3870 }
3871 
runScript(const std::string & name,const std::string & function,bool ignoremissing)3872 bool DSQ::runScript(const std::string &name, const std::string &function, bool ignoremissing /* = false */)
3873 {
3874 	if (!scriptInterface.runScript(name, function, ignoremissing))
3875 	{
3876 		debugLog("Could not find script file [" + name + "]");
3877 	}
3878 	else
3879 	{
3880 		return true;
3881 	}
3882 	return false;
3883 }
3884 
runScriptNum(const std::string & name,const std::string & func,float num)3885 bool DSQ::runScriptNum(const std::string &name, const std::string &func, float num)
3886 {
3887 	if (!scriptInterface.runScriptNum(name, func, num))
3888 	{
3889 		debugLog("Could not find script file [" + name + "]");
3890 	}
3891 	else
3892 	{
3893 		return true;
3894 	}
3895 	return false;
3896 }
3897 
collectScriptGarbage()3898 void DSQ::collectScriptGarbage()
3899 {
3900 	scriptInterface.collectGarbage();
3901 }
3902 
onMouseInput()3903 void DSQ::onMouseInput()
3904 {
3905 	if (dsq->game && dsq->game->avatar)
3906 	{
3907 		if (!dsq->game->isInGameMenu() && !dsq->game->isSceneEditorActive() && !dsq->game->isPaused())
3908 		{
3909 			bool limitRange = true;
3910 			int range = 300;
3911 			if (dsq->game->avatar->singing)
3912 				range = 100;
3913 			else
3914 				limitRange = false;
3915 				//limitRange = core->mouse.buttons.left;
3916 			if (limitRange)
3917 			{
3918 				Vector diff = core->mouse.position - core->center;
3919 				if (diff.getSquaredLength2D() > sqr(range))
3920 				{
3921 					diff.setLength2D(range);
3922 					core->mouse.position = core->center + diff;
3923 				}
3924 			}
3925 		}
3926 	}
3927 }
3928 
3929 //prepare for screenshot or unprepare
prepScreen(bool t)3930 void DSQ::prepScreen(bool t)
3931 {
3932 	if (t)
3933 	{
3934 		cursor->offset = Vector(2000, 0);
3935 		//cursor->renderQuad = false;
3936 		if (game->miniMapRender)
3937 			game->miniMapRender->offset = Vector(2000,0);
3938 		if (fpsText)
3939 			fpsText->offset = Vector(2000,0);
3940 	}
3941 	else
3942 	{
3943 		//cursor->renderQuad = true;
3944 		cursor->offset = Vector(0,0);
3945 		if (game->miniMapRender)
3946 			game->miniMapRender->offset = Vector(0,0);
3947 		if (fpsText)
3948 			fpsText->offset = Vector(0,0);
3949 	}
3950 }
3951 
onRender()3952 void DSQ::onRender()
3953 {
3954 	if (cursor)
3955 	{
3956 		// HACK: not so pretty :D
3957 		if (core->getTopStateObject() == (StateObject*)game)
3958 		{
3959 			if (doScreenshot)
3960 				prepScreen(1);
3961 		}
3962 		cursor->position = mouse.position;
3963 		cursor->position.z = 0;
3964 	}
3965 }
3966 
vision(std::string folder,int num,bool ignoreMusic)3967 void DSQ::vision(std::string folder, int num, bool ignoreMusic)
3968 {
3969 	toggleBlackBars(1);
3970 
3971 	dsq->toggleCursor(false);
3972 	if (game)
3973 		game->togglePause(true);
3974 
3975 	dsq->overlay->color = Vector(1,1,1);
3976 
3977 	float t = 0.1;
3978 
3979 	dsq->game->miniMapRender->toggle(0);
3980 
3981 	fade(1, t);
3982 	main(t);
3983 
3984 	// load images
3985 	typedef std::list<Quad*> QuadList;
3986 	QuadList images;
3987 
3988 	for (int i = num-1; i >= 0; i--)
3989 	{
3990 		Quad *q = new Quad;
3991 		std::string label = "visions/"+folder+"/"+numToZeroString(i, 2)+".png";
3992 		//debugLog(label);
3993 		q->setTexture(label);
3994 		/*
3995 		if (q->getWidth() == q->getHeight())
3996 			q->setWidthHeight(800,800);
3997 		else
3998 			q->setWidthHeight(800,600);
3999 		*/
4000 		q->setWidthHeight(800,600);
4001 		q->followCamera = 1;
4002 		q->position = Vector(400,300);
4003 		images.push_front(q);
4004 		addRenderObject(q, LR_HUD);
4005 	}
4006 
4007 	if (!ignoreMusic)
4008 		sound->setMusicFader(0, t);
4009 
4010 	for (QuadList::iterator i = images.begin(); i != images.end(); i++)
4011 	{
4012 		sound->playSfx("memory-flash");
4013 
4014 		(*i)->scale.interpolateTo(Vector(1.1,1.1), 0.4);
4015 		fade(0, t);
4016 		main(t);
4017 
4018 		main(0.1);
4019 
4020 		fade(1, t);
4021 		main(t);
4022 
4023 		(*i)->alpha = 0;
4024 	}
4025 
4026 	if (game)
4027 		game->togglePause(false);
4028 	dsq->toggleCursor(true);
4029 
4030 	sound->playSfx("memory-flash");
4031 	fade(0, t);
4032 	main(t);
4033 
4034 	for (QuadList::iterator i = images.begin(); i != images.end(); i++)
4035 	{
4036 		(*i)->safeKill();
4037 	}
4038 	images.clear();
4039 
4040 	if (!ignoreMusic)
4041 		sound->setMusicFader(1, t);
4042 
4043 	dsq->overlay->color = Vector(0,0,0);
4044 
4045 	dsq->game->miniMapRender->toggle(1);
4046 
4047 	toggleBlackBars(0);
4048 }
4049 
isDeveloperKeys()4050 bool DSQ::isDeveloperKeys()
4051 {
4052 #ifdef AQUARIA_DEMO
4053 	return false;
4054 #endif
4055 
4056 	return user.system.devModeOn;
4057 }
4058 
canOpenEditor() const4059 bool DSQ::canOpenEditor() const
4060 {
4061 #ifdef AQUARIA_BUILD_SCENEEDITOR
4062 	return dsq->isDeveloperKeys() || (dsq->mod.isActive() && !dsq->mod.isEditorBlocked());
4063 #else
4064 	return false;
4065 #endif
4066 }
4067 
isQuitFlag()4068 bool DSQ::isQuitFlag()
4069 {
4070 	return watchQuitFlag;
4071 }
4072 
watch(float t,int canQuit)4073 void DSQ::watch(float t, int canQuit)
4074 {
4075 	watchQuitFlag = false;
4076 	watchForQuit = false;
4077 
4078 	bool wasInputEnabled = false;
4079 
4080 	if (dsq->game && dsq->game->avatar)
4081 	{
4082 		wasInputEnabled = dsq->game->avatar->isInputEnabled();
4083 
4084 		if (wasInputEnabled)
4085 		{
4086 			dsq->game->avatar->disableInput();
4087 		}
4088 	}
4089 
4090 	core->quitNestedMain();
4091 
4092 	if (canQuit)
4093 	{
4094 		watchForQuit = true;
4095 	}
4096 
4097 	if (t != 0.0f)
4098 		core->main(t);
4099 	else
4100 		errorLog("Called Watch with time == 0");
4101 
4102 	if (canQuit && watchQuitFlag)
4103 	{
4104 		// did it!
4105 	}
4106 
4107 	watchForQuit = false;
4108 
4109 	if (dsq->game && dsq->game->avatar)
4110 	{
4111 		if (wasInputEnabled)
4112 			dsq->game->avatar->enableInput();
4113 	}
4114 }
4115 
action(int id,int state)4116 void DSQ::action(int id, int state)
4117 {
4118 	Core::action(id, state);
4119 
4120 	if (id == ACTION_ESC && !state)
4121 	{
4122 		if (isInCutscene())
4123 		{
4124 			if (isCutscenePaused())
4125 			{
4126 				pauseCutscene(false);
4127 			}
4128 			else
4129 			{
4130 				pauseCutscene(true);
4131 			}
4132 		}
4133 	}
4134 }
4135 
bindInput()4136 void DSQ::bindInput()
4137 {
4138 	clearActions();
4139 
4140 	almb = user.control.actionSet.getActionInputByName("lmb");
4141 	armb = user.control.actionSet.getActionInputByName("rmb");
4142 
4143 	user.control.actionSet.importAction(this, "Escape",		ACTION_ESC);
4144 
4145 #if defined(BBGE_BUILD_MACOSX)
4146 	addAction(MakeFunctionEvent(DSQ, instantQuit), KEY_Q, 1);
4147 #endif
4148 #if defined(BBGE_BUILD_WINDOWS) || defined(BBGE_BUILD_UNIX)
4149 	addAction(MakeFunctionEvent(DSQ, onSwitchScreenMode), KEY_RETURN, 1);
4150 	//addAction(MakeFunctionEvent(DSQ, onAltTab), KEY_TAB, 0);
4151 #endif
4152 	if (isDeveloperKeys())
4153 	{
4154 #ifdef AQUARIA_BUILD_CONSOLE
4155 		addAction(MakeFunctionEvent(DSQ, toggleConsole), KEY_TILDE, 0);
4156 #endif
4157 		addAction(MakeFunctionEvent(DSQ, instantQuit), KEY_Q, 1);
4158 		addAction(MakeFunctionEvent(DSQ, toggleRenderCollisionShapes), KEY_RETURN, 0);
4159 	}
4160 	addAction(MakeFunctionEvent(DSQ, debugMenu), KEY_BACKSPACE, 0);
4161 #if BBGE_BUILD_SDL
4162 	addAction(MakeFunctionEvent(DSQ, takeScreenshot		),		KEY_PRINTSCREEN,	0);
4163 #endif
4164 	addAction(MakeFunctionEvent(DSQ, takeScreenshotKey	),		KEY_P,				0);
4165 }
4166 
jiggleCursor()4167 void DSQ::jiggleCursor()
4168 {
4169 #ifdef BBGE_BUILD_SDL
4170 	// hacky
4171 	SDL_ShowCursor(SDL_ENABLE);
4172 	SDL_ShowCursor(SDL_DISABLE);
4173 #endif
4174 }
4175 
4176 float skipSfxVol = 1.0;
onUpdate(float dt)4177 void DSQ::onUpdate(float dt)
4178 {
4179 	/*
4180 	if (hintTimer > 0)
4181 	{
4182 		hintTimer -= dt;
4183 		if (hintTimer <= 0)
4184 			closeHint();
4185 	}
4186 	*/
4187 
4188 	if (isSkippingCutscene())
4189 	{
4190 		if (!isInCutscene())
4191 		{
4192 			pauseCutscene(false);
4193 			skippingCutscene = false;
4194 			settings.renderOn = true;
4195 			sound->setSfxVolume(skipSfxVol);
4196 		}
4197 		else
4198 		{
4199 			sound->stopVoice();
4200 		}
4201 	}
4202 	else
4203 	{
4204 		if (isCutscenePaused())
4205 		{
4206 			sound->pause();
4207 			float sec = 1.0f/60.0f;
4208 			while (isCutscenePaused())
4209 			{
4210 				pollEvents();
4211 				ActionMapper::onUpdate(sec);
4212 #ifdef BBGE_BUILD_SDL
4213 				SDL_Delay(int(sec*1000));
4214 #endif
4215 				render();
4216 				showBuffer();
4217 				resetTimer();
4218 
4219 				if (_canSkipCutscene && core->getKeyState(KEY_S))
4220 				{
4221 					skippingCutscene = true;
4222 					settings.renderOn = false;
4223 					skipSfxVol = sound->getSfxVol();
4224 					sound->setSfxVolume(0.0);
4225 					resetTimer();
4226 					sound->resume();
4227 					return;
4228 				}
4229 			}
4230 			dsq->resetTimer();
4231 			dsq->sound->resume();
4232 		}
4233 	}
4234 
4235 
4236 	mod.update(dt);
4237 
4238 	lockMouse();
4239 
4240 	if (dsq->game && watchForQuit && isNested())
4241 	{
4242 		if (dsq->game->isActing(ACTION_ESC))
4243 		{
4244 			watchQuitFlag = true;
4245 			quitNestedMain();
4246 		}
4247 	}
4248 
4249 	// messy
4250 	if (versionLabel && versionLabel->alpha.x > 0)
4251 	{
4252 		versionLabel->position = Vector(10 - core->getVirtualOffX(), 575);
4253 	}
4254 
4255 	if (menuSelectDelay > 0)
4256 	{
4257 		menuSelectDelay -= dt;
4258 		if (menuSelectDelay <= 0)
4259 		{
4260 			menuSelectDelay = 0;
4261 		}
4262 	}
4263 
4264 	if (noEffectTimer > 0)
4265 	{
4266 		noEffectTimer -=dt;
4267 		if (noEffectTimer < 0)
4268 			noEffectTimer = 0;
4269 	}
4270 
4271 
4272 	subtitlePlayer.update(dt);
4273 
4274 
4275 	Core::onUpdate(dt);
4276 
4277 	demo.update(dt);
4278 
4279 	// HACK: not optimal
4280 
4281 	if (inputMode != INPUT_KEYBOARD && game->isActive())
4282 	{
4283 		if (almb && (ActionMapper::getKeyState(almb->key[0]) || ActionMapper::getKeyState(almb->key[1])))
4284 			mouse.buttons.left = DOWN;
4285 
4286 		if (armb && (ActionMapper::getKeyState(armb->key[0]) || ActionMapper::getKeyState(armb->key[1])))
4287 			mouse.buttons.right = DOWN;
4288 	}
4289 
4290 	if (joystickAsMouse)
4291 	{
4292 		if (almb && ActionMapper::getKeyState(almb->joy[0]))
4293 			mouse.buttons.left = DOWN;
4294 
4295 		if (armb && ActionMapper::getKeyState(armb->joy[0]))
4296 			mouse.buttons.right = DOWN;
4297 
4298 		/*
4299 		if (routeShoulder)
4300 		{
4301 		if (joystick.leftTrigger > 0.7)
4302 		mouse.buttons.left = DOWN;
4303 		else if (joystick.leftShoulder)
4304 		mouse.buttons.left = DOWN;
4305 		}
4306 		*/
4307 
4308 		/*
4309 		if (joystick.buttons[1])
4310 		mouse.buttons.right = DOWN;
4311 		if (routeShoulder)
4312 		{
4313 		if (joystick.rightTrigger > 0.7)
4314 		mouse.buttons.right = DOWN;
4315 		else if (joystick.rightShoulder)
4316 		mouse.buttons.right = DOWN;
4317 		}
4318 		*/
4319 
4320 		// not going to happen anymore!
4321 		// bye, bye xbox360 controller
4322 		if (!mouse.buttons.middle)
4323 		{
4324 			if (joystick.rightThumb)
4325 				mouse.buttons.middle = DOWN;
4326 			else if (joystick.leftThumb)
4327 				mouse.buttons.middle = DOWN;
4328 		}
4329 
4330 		/*
4331 		if (!mouse.buttons.middle)
4332 			mouse.buttons.middle = joystick.buttons[4];
4333 		*/
4334 		//|| (game->avatar && game->avatar->isSinging())
4335 		/*
4336 		if (core->getTopStateObject() != game || game->isPaused()  || (game->avatar && game->avatar->getState() == Entity::STATE_TITLE))
4337 			core->updateCursorFromJoystick(dt, user.control.joyCursorSpeed);
4338 		else
4339 		{
4340 			core->mouse.position = Vector(400,300);
4341 		}
4342 		*/
4343 
4344 		//core->mouse.position = Vector(400,300);
4345 	}
4346 
4347 	if (joystickEnabled)
4348 	{
4349 		//if (!dsq->game->isInGameMenu())
4350 		{
4351 			if (dsq->inputMode != INPUT_JOYSTICK)
4352 			{
4353 				//if (!core->joystick.position.isZero() || !core->joystick.rightStick.isZero())
4354 				const float thresh = 0.6;
4355 				if (core->joystick.anyButton() || !core->joystick.position.isLength2DIn(thresh) || !core->joystick.rightStick.isLength2DIn(thresh))
4356 				{
4357 					//debugLog("setting joystick input mode");
4358 					dsq->setInputMode(INPUT_JOYSTICK);
4359 				}
4360 			}
4361 			else if (dsq->inputMode != INPUT_MOUSE)
4362 			{
4363 				///if (core->mouse.change.getLength2D() > core->joystick.position.getLength2D())
4364 				//if (!core->mouse.change.isZero())
4365 				if ((!core->mouse.change.isLength2DIn(5) || (core->getMouseButtonState(0) || core->getMouseButtonState(1))) && !core->joystick.anyButton())
4366 				{
4367 					//debugLog("setting mouse input mode");
4368 					dsq->setInputMode(INPUT_MOUSE);
4369 				}
4370 			}
4371 		}
4372 	}
4373 	if (dsq->game->avatar)
4374 	{
4375 		if (dsq->game->avatar->isActing(ACTION_SWIMUP) ||
4376 			dsq->game->avatar->isActing(ACTION_SWIMDOWN) ||
4377 			dsq->game->avatar->isActing(ACTION_SWIMLEFT) ||
4378 			dsq->game->avatar->isActing(ACTION_SWIMRIGHT))
4379 		{
4380 			dsq->setInputMode(INPUT_KEYBOARD);
4381 		}
4382 	}
4383 
4384 	// check the actual values, since mouse.buttons.left might be overwritten by keys
4385 	int cb = 0;
4386 	if (user.control.flipInputButtons)
4387 		cb = 1;
4388 
4389 	if (dsq->inputMode == INPUT_KEYBOARD && (core->getMouseButtonState(cb)))
4390 	{
4391 		dsq->setInputMode(INPUT_MOUSE);
4392 	}
4393 
4394 	/*if (isDeveloperKeys())
4395 	{
4396 		if (core->getCtrlState())
4397 		{
4398 			if (core->getKeyState(KEY_LEFT))
4399 				core->adjustWindowPosition(-5, 0);
4400 			if (core->getKeyState(KEY_RIGHT))
4401 				core->adjustWindowPosition(5, 0);
4402 			if (core->getKeyState(KEY_UP))
4403 				core->adjustWindowPosition(0, -5);
4404 			if (core->getKeyState(KEY_DOWN))
4405 				core->adjustWindowPosition(0, 5);
4406 		}
4407 	}*/
4408 
4409 	if (isDeveloperKeys() && cmDebug && cmDebug->alpha == 1 && fpsText)
4410 	{
4411 		std::ostringstream os;
4412 		/*
4413 		os << "id: " << continuity.cm.id << " - ";
4414 		os << "ego: " << continuity.cm.ego << " - ";
4415 		os << "sEgo: " << continuity.cm.superEgo << " - ";
4416 		os << "cd: " << continuity.cm.getCommonDemoninator();
4417 		os << std::endl;
4418 		*/
4419 		/*
4420 		os << "id.p: " << continuity.cm.getPercentID() << std::endl;
4421 		os << "ego.p: " << continuity.cm.getPercentEGO() << std::endl;
4422 		os << "sEgo.p: " << continuity.cm.getPercentSEGO() << std::endl;
4423 		*/
4424 		if (dsq->game->avatar)
4425 		{
4426 			Avatar *avatar = dsq->game->avatar;
4427 			os << "rolling: " << dsq->game->avatar->isRolling() << " rollDelay: " << dsq->game->avatar->rollDelay << std::endl;
4428 			os << "canChangeForm: " << dsq->game->avatar->canChangeForm << " gamespeed: " << gameSpeed.x << std::endl;
4429 			os << "h: " << dsq->game->avatar->health << " / " << dsq->game->avatar->maxHealth << std::endl;
4430 			os << "biteTimer: " << dsq->game->avatar->biteTimer << " flourTimer: " << dsq->game->avatar->flourishTimer.getValue() << std::endl;
4431 			os << "stillTimer: " << dsq->game->avatar->stillTimer.getValue() << std::endl;
4432 			os << "hp: " << dsq->game->avatar->getHealthPerc() << " flourishPowerTimer: " << dsq->game->avatar->flourishPowerTimer.getValue() << std::endl;
4433 			os << "maxSpeed: " << dsq->game->avatar->currentMaxSpeed << " - ";
4434 			os << "lockedToWall: " << dsq->game->avatar->state.lockedToWall;
4435 			os << std::endl;
4436 			os << "swmng: " << avatar->isSwimming();
4437 			os << " dualFormCharge: " << continuity.dualFormCharge;
4438 			os << std::endl;
4439 			os << "vel(" << avatar->vel.x << ", " << avatar->vel.y << ") ";
4440 			os << "vel2(" << avatar->vel2.x << ", " << avatar->vel2.y << ")";
4441 			os << std::endl;
4442 			os << "rot: " << avatar->rotation.z << " rotoff: " << avatar->rotationOffset.z << std::endl;
4443 			os << "p(" << int(avatar->position.x) << ", " << int(avatar->position.y) << ")" << std::endl;
4444 			os << "inp: " << avatar->isInputEnabled() << std::endl;
4445 			os << "wallNormal(" << avatar->wallNormal.x << ", " << avatar->wallNormal.y << ") collradius: " << avatar->collideRadius << std::endl;
4446 			os << "burst: " << avatar->burst << " burstTimer: " << avatar->burstTimer << std::endl;
4447 			os << "inCurrent: " << avatar->isInCurrent() << std::endl;
4448 			os << "qsongCastDelay: " << avatar->quickSongCastDelay << std::endl;
4449 			os << "singing: " << dsq->game->avatar->singing << " blockSinging: " << dsq->game->avatar->isBlockSinging();
4450 			os << " look: " << dsq->game->avatar->state.updateLookAtTime << " ";
4451 
4452 			os << "inputMode: ";
4453 			switch(dsq->inputMode)
4454 			{
4455 			case INPUT_MOUSE:
4456 				os << "mouse";
4457 			break;
4458 			case INPUT_JOYSTICK:
4459 				os << "joystick";
4460 			break;
4461 			}
4462 			os << std::endl;
4463 			Bone *b = dsq->game->avatar->skeletalSprite.getBoneByIdx(1);
4464 			if (b)
4465 				os << " headRot: " << b->rotation.z;
4466 			os << std::endl;
4467 			os << "fh: " << dsq->game->avatar->isfh() << " fv: " << dsq->game->avatar->isfv() << std::endl;
4468 			os << "canActivate: " << dsq->game->avatar->canActivateStuff();
4469 			os << " canBurst: " << dsq->game->avatar->canBurst();
4470 			os << " canLTW: " << dsq->game->avatar->canLockToWall();
4471 			os << " canSAC: " << dsq->game->avatar->canSwimAgainstCurrents() << std::endl;
4472 		}
4473 
4474 		// DO NOT CALL AVATAR-> beyond this point
4475 		os << "story: " << continuity.getStory() << std::endl;
4476 		os << "invGlobalScale: " << core->invGlobalScale;
4477 		os << std::endl;
4478 		os << "globalScale: " << core->globalScale.x << std::endl;
4479 		os << "mousePos:(" << core->mouse.position.x << ", " << core->mouse.position.y << ") mouseChange:(" << core->mouse.change.x << ", " << core->mouse.change.y << ")\n";
4480 		os << "joyStick:(" << core->joystick.position.x << ", " << core->joystick.position.y << ")\n";
4481 		os << "altState: " << core->getKeyState(KEY_LALT) << " | " << core->getKeyState(KEY_RALT) << std::endl;
4482 		os << "PMFree: " << particleManager->getFree() << " Active: " << particleManager->getNumActive() << std::endl;
4483 		os << "cameraPos: (" << dsq->cameraPos.x << ", " << dsq->cameraPos.y << ")" << std::endl;
4484 		os << "worldType: " << continuity.getWorldType() << " worldPaused: " << game->isWorldPaused() << std::endl;
4485 		os << "voiceTime: " << dsq->sound->getVoiceTime() << " bNat: " << dsq->game->bNatural;
4486 		int ca, ma;
4487 		dsq->sound->getStats(&ca, &ma);
4488 		os << " ca: " << ca << " ma: " << ma << std::endl;
4489 		os << dsq->sound->getVolumeString() << std::endl;
4490 		os << "runInBG: " << core->settings.runInBackground << " nested: " << core->getNestedMains() << std::endl;
4491 		os << core->globalResolutionScale.x << ", " << core->globalResolutionScale.y << std::endl;
4492 		os << "elemu: " << game->elementUpdateList.size() << " elemi: " << game->elementInteractionList.size() << std::endl;
4493 		os << "Lua mem: " << scriptInterface.gcGetStats() << " KB" << std::endl;
4494 
4495 		cmDebug->setText(os.str());
4496 	}
4497 
4498 	if (isDeveloperKeys() && fpsText && cmDebug && cmDebug->alpha == 1)
4499 	{
4500 		std::ostringstream os;
4501 		os << "FPS: " << core->fps << " | ROC: " << core->renderObjectCount << " | RC: " << Core::dbg_numRenderCalls << " | RES: " << core->resources.size();
4502 		os << " | p: " << core->processedRenderObjectCount << " | t: " << core->totalRenderObjectCount;
4503 		os << " | s: " << dsq->continuity.seconds;
4504 		os << " | evQ: " << core->eventQueue.getSize();
4505 		os << " | sndQ: " << core->dbg_numThreadDecoders;
4506 		os << " | dt: " << core->get_current_dt();
4507 		/*
4508 		os << " | s: " << dsq->continuity.seconds;
4509 		os << " cr: " << core->cullRadius;
4510 		os << " r: " << core->redBits << " g: " << core->greenBits << " b: " << core->blueBits;
4511 		os << " a: " << core->alphaBits;
4512 		*/
4513 		//<< "(" << core->mouse.position.x << ", " << core->mouse.position.y << ")";
4514 		// << "|"
4515 		//os << float(1/dt) << " Instant";
4516 		fpsText->setText(os.str());
4517 	}
4518 
4519 	if (shakeCameraTimer > 0)
4520 	{
4521 		shakeCameraTimer -= dt;
4522 		if (shakeCameraTimer <= 0)
4523 		{
4524 			shakeCameraTimer = 0;
4525 			cameraOffset = Vector(0,0);
4526 		}
4527 		else
4528 		{
4529 			cameraOffset = Vector((rand()%int(shakeCameraMag))-shakeCameraMag/2.0f, (rand()%int(shakeCameraMag))-shakeCameraMag/2.0f);
4530 		}
4531 	}
4532 
4533 	static int lastWidth = 0;
4534 	static int lastHeight = 0;
4535 	if (lastWidth != width || lastHeight != height) {
4536 		setInpGrab = -1;
4537 	}
4538 	lastWidth = width;
4539 	lastHeight = height;
4540 
4541 	static bool lastfullscreen = false;
4542 
4543 	if (lastfullscreen != _fullscreen)
4544 	{
4545 		setInpGrab = -1;
4546 	}
4547 	lastfullscreen = _fullscreen;
4548 
4549 	if (game && game->avatar && game->avatar->isInputEnabled() && !game->isPaused() && !game->isInGameMenu())
4550 	{
4551 		//debugLog("enabled");
4552 		if (setInpGrab != 1)
4553 		{
4554 			toggleInputGrabPlat(true);
4555 			setInpGrab = 1;
4556 		}
4557 	}
4558 	else
4559 	{
4560 		//debugLog("not enabled");
4561 		if (setInpGrab != 0)
4562 		{
4563 			toggleInputGrabPlat(false);
4564 			setInpGrab = 0;
4565 		}
4566 	}
4567 
4568 
4569 
4570 
4571 	updatepecue(dt);
4572 
4573 
4574 	lockMouse();
4575 
4576 	Network::update();
4577 
4578 	Shot::clearShotGarbage();
4579 }
4580 
lockMouse()4581 void DSQ::lockMouse()
4582 {
4583 	/*
4584 	if (core->getVirtualWidth() > 800 && core->mouse.position.x >= 800)
4585 	{
4586 		core->mouse.position.x = 800;
4587 		core->setMousePosition(core->mouse.position);
4588 	}
4589 	*/
4590 }
4591 
shakeCamera(float mag,float time)4592 void DSQ::shakeCamera(float mag, float time)
4593 {
4594 	cameraOffset = Vector(0,0);
4595 	shakeCameraMag = mag;
4596 	shakeCameraTimer = time;
4597 }
4598 
isShakingCamera()4599 bool DSQ::isShakingCamera()
4600 {
4601 	return (shakeCameraTimer > 0);
4602 }
4603 
isScriptRunning()4604 bool DSQ::isScriptRunning()
4605 {
4606 	if (nestedMains>1)
4607 	{
4608 		return true;
4609 	}
4610 	else
4611 	{
4612 		return false;
4613 	}
4614 }
4615 
delay(float dt)4616 void DSQ::delay(float dt)
4617 {
4618 	core->main(dt);
4619 }
4620 
fade(float alpha,float time)4621 void DSQ::fade(float alpha, float time)
4622 {
4623 	if (overlay)
4624 		overlay->alpha.interpolateTo(alpha, time,0);
4625 }
4626 
toggleCursor(bool v,float time)4627 void DSQ::toggleCursor(bool v, float time)
4628 {
4629 	if (!cursor) return;
4630 	float t = time;
4631 	if (time == -1)
4632 		t = 0.1;
4633 	if (!v)
4634 		cursor->alpha.interpolateTo(0, t);
4635 	else
4636 		cursor->alpha.interpolateTo(1, t);
4637 }
4638 
playVisualEffect(int vfx,Vector position,Entity * target)4639 void DSQ::playVisualEffect(int vfx, Vector position, Entity *target)
4640 {
4641 	switch(vfx)
4642 	{
4643 	case VFX_SHOCK:
4644 	{
4645 		/*
4646 		dsq->game->sceneColor2 = Vector(1,1,1);
4647 		dsq->game->sceneColor2.interpolateTo(Vector(1,0.7,0.7), 1.2, 1, 1);
4648 		*/
4649 
4650 		//dsq->game->avatar->damage(1);
4651 		core->sound->playSfx("ShockWave");
4652 		//dsq->spawnParticleEffect("ShockWave", position);
4653 		float t =1.0;
4654 
4655 		Quad *q = new Quad;
4656 		q->position = position;
4657 		q->scale = Vector(0,0);
4658 		q->scale.interpolateTo(Vector(5,5),t);
4659 		/*
4660 		q->color = Vector(1,1,1);
4661 		q->color.interpolateTo(Vector(1,0,0),t-t*0.05f);
4662 		*/
4663 		q->alpha.ensureData();
4664 		q->alpha.data->path.addPathNode(0, 0);
4665 		q->alpha.data->path.addPathNode(0.75, 0.25);
4666 		q->alpha.data->path.addPathNode(0.75, 0.75);
4667 		q->alpha.data->path.addPathNode(0, 1);
4668 		q->alpha.startPath(t);
4669 		q->setBlendType(RenderObject::BLEND_ADD);
4670 		q->setTexture("particles/EnergyRing");
4671 		if (target)
4672 			q->positionSnapTo = &target->position;
4673 		//q->rotation.interpolateTo(Vector(0,0,360), t+0.1f);
4674 		game->addRenderObject(q, LR_PARTICLES);
4675 
4676 		if (target && target->getEntityType() == ET_AVATAR)
4677 			if (core->afterEffectManager)
4678 				core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.08,0.05,22,0.2f, 1.2));
4679 
4680 		t = 0.75;
4681 		{
4682 			Quad *q = new Quad;
4683 			q->position = position;
4684 			q->scale = Vector(0.5,0.5);
4685 			q->scale.interpolateTo(Vector(2,2),t);
4686 			q->alpha.ensureData();
4687 			q->alpha.data->path.addPathNode(0, 0);
4688 			q->alpha.data->path.addPathNode(0.75, 0.25);
4689 			q->alpha.data->path.addPathNode(0.75, 0.75);
4690 			q->alpha.data->path.addPathNode(0, 1);
4691 			q->alpha.startPath(t);
4692 			q->setBlendType(RenderObject::BLEND_ADD);
4693 			q->setTexture("particles/EnergyPart");
4694 			if (target)
4695 				q->positionSnapTo = &target->position;
4696 			q->rotation.z = rand()%360;
4697 			game->addRenderObject(q, LR_PARTICLES);
4698 		}
4699 	}
4700 	break;
4701 	case VFX_SHOCKHIT:
4702 	{
4703 		float t = 1.0;
4704 		{
4705 		Quad *q = new Quad;
4706 		q->position = position;
4707 		q->scale = Vector(1,1);
4708 		q->scale.interpolateTo(Vector(3,3),t);
4709 		q->alpha.ensureData();
4710 		q->alpha.data->path.addPathNode(0, 0);
4711 		q->alpha.data->path.addPathNode(1, 0.3);
4712 		//q->alpha.data->path.addPathNode(0.75, 0.75);
4713 		q->alpha.data->path.addPathNode(0, 1);
4714 		q->alpha.startPath(t);
4715 		q->setBlendType(RenderObject::BLEND_ADD);
4716 		q->rotation.z = rand()%360;
4717 		q->setTexture("particles/EnergyRing");
4718 		/*
4719 		if (target)
4720 			q->positionSnapTo = &target->position;
4721 		*/
4722 		q->rotation.interpolateTo(Vector(0,0,q->rotation.z + 360), t+0.1f);
4723 		game->addRenderObject(q, LR_PARTICLES);
4724 		}
4725 
4726 		t = 0.75;
4727 		{
4728 			Quad *q = new Quad;
4729 			q->position = position;
4730 			q->scale = Vector(1,1);
4731 			q->scale.interpolateTo(Vector(3,3),t);
4732 			q->alpha.ensureData();
4733 			q->alpha.data->path.addPathNode(0, 0);
4734 			q->alpha.data->path.addPathNode(0.8, 0.25);
4735 			//q->alpha.data->path.addPathNode(0.75, 0.75);
4736 			q->alpha.data->path.addPathNode(0, 1);
4737 			q->alpha.startPath(t);
4738 			q->setBlendType(RenderObject::BLEND_ADD);
4739 			/*
4740 			if (target)
4741 				q->positionSnapTo = &target->position;
4742 			*/
4743 			q->setTexture("particles/EnergyDeltas");
4744 			q->rotation.z = rand()%360;
4745 			//q->rotation.interpolateTo(Vector(0,0,-360), t+0.1f);
4746 			game->addRenderObject(q, LR_PARTICLES);
4747 		}
4748 	}
4749 	break;
4750 	case VFX_RIPPLE:
4751 		if (core->afterEffectManager)
4752 			core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.04,0.06,15,0.2f));
4753 	break;
4754 	/*
4755 	case VFX_BIGRIPPLE:
4756 	break;
4757 	*/
4758 	}
4759 }
4760 
addElement(Element * e)4761 void DSQ::addElement(Element *e)
4762 {
4763 	elements.push_back(e);
4764 	if (e->bgLayer >= 0 && e->bgLayer < 16)
4765 	{
4766 		e->bgLayerNext = firstElementOnLayer[e->bgLayer];
4767 		firstElementOnLayer[e->bgLayer] = e;
4768 	}
4769 	else
4770 	{
4771 		e->bgLayerNext = 0;
4772 	}
4773 }
4774 
modifyDt(float & dt)4775 void DSQ::modifyDt(float &dt)
4776 {
4777 	if (isDeveloperKeys())
4778 	{
4779 		if (core->getKeyState(KEY_G))
4780 		{
4781 			if(core->getShiftState())
4782 				dt *= 10;
4783 			else
4784 				dt *= 4;
4785 		}
4786 		else if (core->getKeyState(KEY_F))
4787 		{
4788 			if (core->getShiftState())
4789 				dt *= 0.1f;
4790 			else
4791 				dt *= 0.6;
4792 		}
4793 		else if (core->getKeyState(KEY_H))
4794 			dt = FRAME_TIME;
4795 		else
4796 		{
4797 			// frame cap
4798 			if (dt > FRAME_TIME)
4799 				dt = FRAME_TIME;
4800 		}
4801 		if (core->getKeyState(KEY_H))
4802 			stopVoice();
4803 	}
4804 	else
4805 	{
4806 		if (dt > FRAME_TIME)
4807 			dt = FRAME_TIME;
4808 	}
4809 
4810 	if (skippingCutscene)
4811 		dt = 0.07f;
4812 
4813 	gameSpeed.update(dt);
4814 	dt *= gameSpeed.x;
4815 
4816 	if (frameOutputMode)
4817 	{
4818 		dt = 1.0f/60.0f;
4819 		doScreenshot = true;
4820 	}
4821 
4822 	if (dsq->demo.mode == Demo::DEMOMODE_RECORD)
4823 	{
4824 		dt = 1.0f/60.0f;
4825 	}
4826 }
4827 
removeElement(Element * element)4828 void DSQ::removeElement(Element *element)
4829 {
4830 	for (int i = 0; i < dsq->elements.size(); i++)
4831 	{
4832 		if (dsq->elements[i] == element)
4833 		{
4834 			removeElement(i);
4835 			break;
4836 		}
4837 	}
4838 
4839 }
4840 // only happens in editor, no need to optimize
removeElement(int idx)4841 void DSQ::removeElement(int idx)
4842 {
4843 	ElementContainer copy = elements;
4844 	clearElements();
4845 	int i = 0;
4846 	for (i = 0; i < idx; i++)
4847 	{
4848 		addElement(copy[i]);
4849 	}
4850 	for (i = idx+1; i < copy.size(); i++)
4851 	{
4852 		addElement(copy[i]);
4853 	}
4854 	copy.clear();
4855 
4856 	if (!dsq->game->elementUpdateList.empty())
4857 		dsq->game->rebuildElementUpdateList();
4858 }
4859 
clearElements()4860 void DSQ::clearElements()
4861 {
4862 	elements.clear();
4863 	for (int i = 0; i < 16; i++)
4864 		firstElementOnLayer[i] = 0;
4865 }
4866 
4867 
addEntity(Entity * entity)4868 void DSQ::addEntity(Entity *entity)
4869 {
4870 	int i;
4871 	for (i = 0; entities[i] != 0; i++) {}
4872 	if (i+1 >= entities.size())
4873 		entities.resize(entities.size()*2, 0);
4874 	entities[i] = entity;
4875 	entities[i+1] = 0;
4876 }
4877 
removeEntity(Entity * entity)4878 void DSQ::removeEntity(Entity *entity)
4879 {
4880 	int i;
4881 	for (i = 0; entities[i] != 0; i++)
4882 	{
4883 		if (entities[i] == entity)
4884 			break;
4885 	}
4886 	for (; entities[i] != 0; i++)
4887 	{
4888 		entities[i] = entities[i+1];
4889 	}
4890 }
4891 
clearEntities()4892 void DSQ::clearEntities()
4893 {
4894 	const int size = entities.size();
4895 	int i;
4896 	for (i = 0; i < size; i++)
4897 	{
4898 		entities[i] = 0;
4899 	}
4900 }
4901 
4902 
getSaveDirectory()4903 std::string DSQ::getSaveDirectory()
4904 {
4905 	return getUserDataFolder() + "/save";
4906 }
4907 
spawnParticleEffect(const std::string & name,Vector position,float rotz,float t,int layer,float follow)4908 ParticleEffect *DSQ::spawnParticleEffect(const std::string &name, Vector position, float rotz, float t, int layer, float follow)
4909 {
4910 	if (name.empty())
4911 		return NULL;
4912 	if (t!=0)
4913 	{
4914 		PECue p(name, position, rotz, t);
4915 		pecue.push_back(p);
4916 		return NULL;
4917 	}
4918 
4919 	ParticleEffect *e = core->createParticleEffect(name, position, layer, rotz);
4920 	e->followCamera = follow;
4921 	return e;
4922 }
4923 
spawnAllIngredients(const Vector & position)4924 void DSQ::spawnAllIngredients(const Vector &position)
4925 {
4926 	continuity.spawnAllIngredients(position);
4927 }
4928 
updatepecue(float dt)4929 void DSQ::updatepecue(float dt)
4930 {
4931 	if (!core->particlesPaused)
4932 	{
4933 		//for (std::vector<PECue>::iterator i = pecue.begin(); i != pecue.end(); i++)
4934 		int nz = 0;
4935 		for (int i = 0; i < pecue.size(); i++)
4936 		{
4937 			PECue *p = &pecue[i];
4938 			if (p->t > 0)
4939 			{
4940 				p->t -= dt;
4941 				if (p->t < 0)
4942 				{
4943 					p->t = 0;
4944 					spawnParticleEffect(p->name, p->pos, p->rot, 0);
4945 				}
4946 				nz ++;
4947 			}
4948 		}
4949 		// lazy ass delete
4950 		if (nz == 0)
4951 		{
4952 			pecue.clear();
4953 		}
4954 	}
4955 }
4956 
capture()4957 void AquariaScreenTransition::capture()
4958 {
4959 	this->alpha = 0;
4960 	InterpolatedVector oldAlpha = dsq->cursor->alpha;
4961 	dsq->cursor->alpha.x = 0;
4962 	int width=0, height=0;
4963 	core->render();
4964 
4965 	width = core->getWindowWidth();
4966 	height = core->getWindowHeight();
4967 
4968 #ifdef BBGE_BUILD_OPENGL
4969 	glBindTexture(GL_TEXTURE_2D,screen_texture);
4970 	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
4971 #endif
4972 
4973 
4974 	dsq->cursor->alpha = oldAlpha;
4975 	core->render();
4976 	core->showBuffer();
4977 
4978 	this->alpha = 1;
4979 	//ScreenTransition::capture();
4980 }
4981 
setCutscene(bool on,bool canSkip)4982 void DSQ::setCutscene(bool on, bool canSkip)
4983 {
4984 	inCutscene = on;
4985 	_canSkipCutscene = canSkip;
4986 }
4987 
canSkipCutscene()4988 bool DSQ::canSkipCutscene()
4989 {
4990 	return _canSkipCutscene;
4991 }
4992 
isSkippingCutscene()4993 bool DSQ::isSkippingCutscene()
4994 {
4995 	return skippingCutscene;
4996 }
4997 
isInCutscene()4998 bool DSQ::isInCutscene()
4999 {
5000 	return inCutscene;
5001 }
5002 
isCutscenePaused()5003 bool DSQ::isCutscenePaused()
5004 {
5005 	return cutscenePaused;
5006 }
5007 
pauseCutscene(bool on)5008 void DSQ::pauseCutscene(bool on)
5009 {
5010 	cutscenePaused = on;
5011 
5012 	cutsceneEffects(on);
5013 }
5014 
cutsceneEffects(bool on)5015 void DSQ::cutsceneEffects(bool on)
5016 {
5017 	if (cutscene_bg && cutscene_text && cutscene_text2)
5018 	{
5019 		if (canSkipCutscene())
5020 		{
5021 			cutscene_text->offset = Vector(0, -10);
5022 			cutscene_text2->offset = Vector(0, -10);
5023 		}
5024 		else
5025 		{
5026 			cutscene_text->offset = Vector(0,0);
5027 			cutscene_text2->offset = Vector(0,0);
5028 		}
5029 		cutscene_bg->alpha.x = on?1:0;
5030 		cutscene_text->alpha.x = on?1:0;
5031 		cutscene_text2->alpha.x = (on&&dsq->canSkipCutscene())?1:0;
5032 	}
5033 }
5034 
onBackgroundUpdate()5035 void DSQ::onBackgroundUpdate()
5036 {
5037 	Network::update();
5038 	Core::onBackgroundUpdate();
5039 }
5040 
resetLayerPasses()5041 void DSQ::resetLayerPasses()
5042 {
5043 	for(size_t i = 0; i < renderObjectLayers.size(); ++i)
5044 	{
5045 		renderObjectLayers[i].startPass = 0;
5046 		renderObjectLayers[i].endPass = 0;
5047 	}
5048 	renderObjectLayers[LR_ENTITIES].startPass = -2;
5049 	renderObjectLayers[LR_ENTITIES].endPass = 5;
5050 }
5051 
isMiniMapCursorOkay()5052 bool DSQ::isMiniMapCursorOkay()
5053 {
5054 	return ((inputMode != INPUT_MOUSE) ||  (!game->miniMapRender || !game->miniMapRender->isCursorIn()));
5055 }
5056 
5057