MegaGlest/source/glest_game/main/intro.cpp

467 lines
15 KiB
C++
Raw Normal View History

// ==============================================================
// This file is part of Glest (www.glest.org)
//
2010-04-13 21:08:08 +02:00
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "intro.h"
#include "main_menu.h"
#include "util.h"
#include "game_util.h"
#include "config.h"
#include "program.h"
#include "renderer.h"
#include "sound_renderer.h"
#include "core_data.h"
#include "metrics.h"
#include "auto_test.h"
#include "util.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace Shared::Graphics;
using namespace Shared::Xml;
namespace Glest{ namespace Game{
// =====================================================
// class Text
// =====================================================
Text::Text(const string &text, const Vec2i &pos, int time, Font2D *font, Font3D *font3D) {
this->text= text;
this->pos= pos;
this->time= time;
this->texture= NULL;
this->font= font;
this->font3D = font3D;
}
2011-06-06 23:38:25 +02:00
Text::Text(const Texture2D *texture, const Vec2i &pos, const Vec2i &size, int time) {
this->pos= pos;
this->size= size;
this->time= time;
this->texture= texture;
this->font= NULL;
2011-09-01 01:10:43 +02:00
this->font3D=NULL;
}
// =====================================================
// class Intro
// =====================================================
int Intro::introTime = 50000;
int Intro::appearTime = 2500;
int Intro::showTime = 3500;
int Intro::disapearTime = 2500;
Intro::Intro(Program *program):
ProgramState(program)
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
CoreData &coreData= CoreData::getInstance();
const Metrics &metrics= Metrics::getInstance();
int w= metrics.getVirtualW();
int h= metrics.getVirtualH();
timer=0;
mouseX = 0;
mouseY = 0;
mouse2d = 0;
Renderer &renderer= Renderer::getInstance();
//renderer.init3dListMenu(NULL);
renderer.initMenu(NULL);
fade= 0.f;
anim= 0.f;
XmlTree xmlTree;
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
xmlTree.load(data_path + "data/core/menu/menu.xml",Properties::getTagReplacementValues());
const XmlNode *menuNode= xmlTree.getRootNode();
const XmlNode *introNode= menuNode->getChild("intro");
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
targetCamera= NULL;
t= 0.f;
//camera
const XmlNode *cameraNode= introNode->getChild("camera");
//position
const XmlNode *positionNode= cameraNode->getChild("start-position");
startPosition.x= positionNode->getAttribute("x")->getFloatValue();
startPosition.y= positionNode->getAttribute("y")->getFloatValue();
startPosition.z= positionNode->getAttribute("z")->getFloatValue();
camera.setPosition(startPosition);
//rotation
const XmlNode *rotationNode= cameraNode->getChild("start-rotation");
Vec3f startRotation;
startRotation.x= rotationNode->getAttribute("x")->getFloatValue();
startRotation.y= rotationNode->getAttribute("y")->getFloatValue();
startRotation.z= rotationNode->getAttribute("z")->getFloatValue();
camera.setOrientation(Quaternion(EulerAngles(
degToRad(startRotation.x),
degToRad(startRotation.y),
degToRad(startRotation.z))));
// intro info
const XmlNode *introTimeNode= introNode->getChild("intro-time");
Intro::introTime = introTimeNode->getAttribute("value")->getIntValue();
const XmlNode *appearTimeNode= introNode->getChild("appear-time");
Intro::appearTime = appearTimeNode->getAttribute("value")->getIntValue();
const XmlNode *showTimeNode= introNode->getChild("show-time");
Intro::showTime = showTimeNode->getAttribute("value")->getIntValue();
const XmlNode *disappearTimeNode= introNode->getChild("disappear-time");
Intro::disapearTime = disappearTimeNode->getAttribute("value")->getIntValue();
const XmlNode *showIntroPicturesNode= introNode->getChild("show-intro-pictures");
int showIntroPics = showIntroPicturesNode->getAttribute("value")->getIntValue();
int showIntroPicsTime = showIntroPicturesNode->getAttribute("time")->getIntValue();
bool showIntroPicsRandom = showIntroPicturesNode->getAttribute("random")->getBoolValue();
const XmlNode *showIntroModelsNode= introNode->getChild("show-intro-models");
bool showIntroModels = showIntroModelsNode->getAttribute("value")->getBoolValue();
bool showIntroModelsRandom = showIntroModelsNode->getAttribute("random")->getBoolValue();
//load main model
modelIndex = 0;
models.clear();
if(showIntroModels == true) {
string introPath = data_path + "data/core/menu/main_model/intro*.g3d";
vector<string> introModels;
findAll(introPath, introModels, false, false);
for(int i = 0; i < introModels.size(); ++i) {
string logo = introModels[i];
Model *model= renderer.newModel(rsMenu);
if(model) {
model->load(data_path + "data/core/menu/main_model/" + logo);
models.push_back(model);
//printf("model [%s]\n",model->getFileName().c_str());
}
}
if(showIntroModelsRandom == true) {
std::vector<Model *> modelList;
unsigned int seed = time(NULL);
srand(seed);
int failedLookups=0;
std::map<int,bool> usedIndex;
for(;modelList.size() < models.size();) {
int index = rand() % models.size();
if(usedIndex.find(index) != usedIndex.end()) {
failedLookups++;
seed = time(NULL) / failedLookups;
srand(seed);
continue;
}
//printf("picIndex = %d list count = %d\n",picIndex,coreData.getMiscTextureList().size());
modelList.push_back(models[index]);
usedIndex[index]=true;
seed = time(NULL) / modelList.size();
srand(seed);
}
models = modelList;
}
}
int displayItemNumber = 1;
int appear= Intro::appearTime;
int disappear= Intro::showTime+Intro::appearTime+Intro::disapearTime;
texts.push_back(new Text("based on the award winning game Glest", Vec2i(w/2, h/2), appear, coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D()));
texts.push_back(new Text("the MegaGlest team presents...", Vec2i(w/2, h/2), disappear, coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D()));
texts.push_back(new Text(coreData.getLogoTexture(), Vec2i(w/2-128, h/2-64), Vec2i(256, 128), disappear *(++displayItemNumber)));
texts.push_back(new Text(glestVersionString, Vec2i(w/2+45, h/2-45), disappear *(displayItemNumber++), coreData.getMenuFontNormal(),coreData.getMenuFontNormal3D()));
texts.push_back(new Text("www.megaglest.org", Vec2i(w/2, h/2), disappear *(displayItemNumber++), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D()));
modelShowTime = disappear *(displayItemNumber);
if(showIntroPics > 0 && coreData.getMiscTextureList().size() > 0) {
const int showMiscTime = showIntroPicsTime;
std::vector<Texture2D *> intoTexList;
if(showIntroPicsRandom == true) {
unsigned int seed = time(NULL);
srand(seed);
int failedLookups=0;
std::map<int,bool> usedIndex;
for(;intoTexList.size() < showIntroPics;) {
int picIndex = rand() % coreData.getMiscTextureList().size();
if(usedIndex.find(picIndex) != usedIndex.end()) {
failedLookups++;
seed = time(NULL) / failedLookups;
srand(seed);
continue;
}
//printf("picIndex = %d list count = %d\n",picIndex,coreData.getMiscTextureList().size());
intoTexList.push_back(coreData.getMiscTextureList()[picIndex]);
usedIndex[picIndex]=true;
seed = time(NULL) / intoTexList.size();
srand(seed);
}
}
else {
for(unsigned int i = 0;
i < coreData.getMiscTextureList().size() &&
i < showIntroPics; ++i) {
Texture2D *tex = coreData.getMiscTextureList()[i];
intoTexList.push_back(tex);
}
}
for(unsigned int i = 0; i < intoTexList.size(); ++i) {
Texture2D *tex = intoTexList[i];
//printf("tex # %d [%s]\n",i,tex->getPath().c_str());
Vec2i texPlacement;
if(i == 0 || i % 9 == 0) {
texPlacement = Vec2i(1, h-tex->getTextureHeight());
}
else if(i == 1 || i % 9 == 1) {
texPlacement = Vec2i(1, 1);
}
else if(i == 2 || i % 9 == 2) {
texPlacement = Vec2i(w-tex->getTextureWidth(), 1);
}
else if(i == 3 || i % 9 == 3) {
texPlacement = Vec2i(w-tex->getTextureWidth(), h-tex->getTextureHeight());
}
else if(i == 4 || i % 9 == 4) {
texPlacement = Vec2i(w/2 - tex->getTextureWidth()/2, h-tex->getTextureHeight());
}
else if(i == 5 || i % 9 == 5) {
texPlacement = Vec2i(w/2 - tex->getTextureWidth()/2, 1);
}
else if(i == 6 || i % 9 == 6) {
texPlacement = Vec2i(1, (h/2) - (tex->getTextureHeight()/2));
}
else if(i == 7 || i % 9 == 7) {
texPlacement = Vec2i(w-tex->getTextureWidth(), (h/2) - (tex->getTextureHeight()/2));
}
texts.push_back(new Text(tex, texPlacement, Vec2i(tex->getTextureWidth(), tex->getTextureHeight()), disappear *displayItemNumber+(showMiscTime*(i+1))));
}
}
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
soundRenderer.playMusic(CoreData::getInstance().getIntroMusic());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
Intro::~Intro() {
deleteValues(texts.begin(),texts.end());
}
void Intro::update() {
timer++;
if(timer > introTime * GameConstants::updateFps / 1000){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
cleanup();
2011-02-18 17:15:14 +01:00
return;
}
if(Config::getInstance().getBool("AutoTest")){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
AutoTest::getInstance().updateIntro(program);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim;
if(targetCamera != NULL) {
t+= ((0.01f+(1.f-t)/10.f)/20.f)*(60.f/GameConstants::updateFps);
//interpolate position
camera.setPosition(lastCamera.getPosition().lerp(t, targetCamera->getPosition()));
//interpolate orientation
Quaternion q= lastCamera.getOrientation().lerp(t, targetCamera->getOrientation());
camera.setOrientation(q);
if(t>=1.f){
targetCamera= NULL;
t= 0.f;
}
}
//fade
if(fade <= 1.f) {
fade += 0.6f / GameConstants::updateFps;
if(fade > 1.f){
fade = 1.f;
}
}
//animation
const float minSpeed = 0.015f;
const float maxSpeed = 0.6f;
anim += (maxSpeed / GameConstants::updateFps) / 5 + random.randRange(minSpeed, max(minSpeed + 0.0001f, (maxSpeed / GameConstants::updateFps) / 5.f));
if(anim > 1.f) {
anim = 0.f;
}
}
void Intro::renderModelBackground() {
// Black background
glClearColor(0, 0, 0, 1);
if(models.size() > 0) {
int difTime= 1000 * timer / GameConstants::updateFps - modelShowTime;
int totalModelShowTime = Intro::introTime - modelShowTime;
int individualModelShowTime = totalModelShowTime / models.size();
//printf("difTime = %d individualModelShowTime = %d modelIndex = %d\n",difTime,individualModelShowTime,modelIndex);
//int difTime= 1;
if(difTime > 0) {
if(difTime > ((modelIndex+1) * individualModelShowTime)) {
int oldmodelIndex = modelIndex;
if(modelIndex+1 < models.size()) {
modelIndex++;
//position
//nextCamera.setPosition(camera.getPosition());
// nextCamera.setPosition(Vec3f(84,-9,11));
//
// //rotation
// //Vec3f startRotation(0,12,0);
// Vec3f startRotation(0,-80,0);
// nextCamera.setOrientation(Quaternion(EulerAngles(
// degToRad(startRotation.x),
// degToRad(startRotation.y),
// degToRad(startRotation.z))));
//
// this->targetCamera = &nextCamera;
// this->lastCamera= camera;
// this->t= 0.f;
}
//printf("oldmodelIndex = %d, modelIndex = %d\n",oldmodelIndex,modelIndex);
}
Renderer &renderer= Renderer::getInstance();
vector<Model *> characterModels;
characterModels.push_back(NULL);
characterModels.push_back(NULL);
characterModels.push_back(models[modelIndex]);
const Vec3f characterPosition = startPosition;
renderer.renderMenuBackground(&camera, fade, NULL, characterModels,characterPosition,anim);
}
}
}
2011-06-06 23:38:25 +02:00
void Intro::render() {
Renderer &renderer= Renderer::getInstance();
if(renderer.isMasterserverMode() == true) {
return;
}
int difTime=0;
canRender();
incrementFps();
renderer.clearBuffers();
renderer.reset3dMenu();
renderer.clearZBuffer();
renderer.loadCameraMatrix(&camera);
renderModelBackground();
renderer.renderParticleManager(rsMenu);
renderer.reset2d();
for(int i = 0; i < texts.size(); ++i) {
Text *text= texts[i];
difTime= 1000 * timer / GameConstants::updateFps - text->getTime();
if(difTime > 0 && difTime < appearTime + showTime + disapearTime) {
float alpha= 1.f;
if(difTime > 0 && difTime < appearTime) {
//apearing
alpha= static_cast<float>(difTime) / appearTime;
}
else if(difTime > 0 && difTime < appearTime + showTime + disapearTime) {
//disappearing
alpha= 1.f- static_cast<float>(difTime - appearTime - showTime) / disapearTime;
}
if(text->getText().empty() == false) {
if(Renderer::renderText3DEnabled) {
renderer.renderText3D(
text->getText(), text->getFont3D(), alpha,
text->getPos().x, text->getPos().y, true);
}
else {
renderer.renderText(
text->getText(), text->getFont(), alpha,
text->getPos().x, text->getPos().y, true);
}
}
if(text->getTexture()!=NULL){
renderer.renderTextureQuad(
text->getPos().x, text->getPos().y,
text->getSize().x, text->getSize().y,
text->getTexture(), alpha);
}
}
}
if(program != NULL) program->renderProgramMsgBox();
if(this->forceMouseRender == true) renderer.renderMouse2d(mouseX, mouseY, mouse2d, 0.f);
renderer.renderFPSWhenEnabled(lastFps);
renderer.swapBuffers();
}
void Intro::keyDown(char key){
mouseUpLeft(0, 0);
}
void Intro::mouseUpLeft(int x, int y){
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
soundRenderer.stopMusic(CoreData::getInstance().getIntroMusic());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
soundRenderer.playMusic(CoreData::getInstance().getMenuMusic());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
cleanup();
}
void Intro::cleanup() {
Renderer::getInstance().endMenu();
program->setState(new MainMenu(program));
}
void Intro::mouseMove(int x, int y, const MouseState *ms) {
mouseX = x;
mouseY = y;
}
}}//end namespace