mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
A bit more text-related work:
- credits screen will use multi-line label instead of hackish usage of text box - campaign intro movie player now plays voiced intro - minor fixes to last commit
This commit is contained in:
parent
6bee105d7d
commit
83440f1149
@ -396,7 +396,8 @@ CMenuEntry::CMenuEntry(CMenuScreen* parent, const JsonNode &config)
|
||||
}
|
||||
}
|
||||
|
||||
CreditsScreen::CreditsScreen()
|
||||
CreditsScreen::CreditsScreen():
|
||||
positionCounter(0)
|
||||
{
|
||||
addUsedEvents(LCLICK | RCLICK);
|
||||
type |= REDRAW_PARENT;
|
||||
@ -407,34 +408,19 @@ CreditsScreen::CreditsScreen()
|
||||
std::string text((char*)textFile.first.get(), textFile.second);
|
||||
size_t firstQuote = text.find('\"')+1;
|
||||
text = text.substr(firstQuote, text.find('\"', firstQuote) - firstQuote );
|
||||
credits = new CTextBox(text, Rect(pos.w - 350, 600, 350, 32000), 0, FONT_CREDITS, CENTER, Colors::WHITE);
|
||||
credits->pos.h = credits->label->textSize.y;
|
||||
}
|
||||
|
||||
void CreditsScreen::showAll(SDL_Surface * to)
|
||||
{
|
||||
//Do not draw anything
|
||||
credits = new CMultiLineLabel(Rect(pos.w - 350, 0, 350, 600), FONT_CREDITS, CENTER, Colors::WHITE, text);
|
||||
credits->scrollTextTo(-600); // move all text below the screen
|
||||
}
|
||||
|
||||
void CreditsScreen::show(SDL_Surface * to)
|
||||
{
|
||||
static int count = 0;
|
||||
count++;
|
||||
if (count == 2)
|
||||
{
|
||||
credits->pos.y--;
|
||||
count = 0;
|
||||
}
|
||||
Rect creditsArea = credits->pos & pos;
|
||||
SDL_SetClipRect(screenBuf, &creditsArea);
|
||||
SDL_SetClipRect(screen, &creditsArea);
|
||||
redraw();
|
||||
CIntObject::showAll(to);
|
||||
SDL_SetClipRect(screen, nullptr);
|
||||
SDL_SetClipRect(screenBuf, nullptr);
|
||||
CIntObject::show(to);
|
||||
positionCounter++;
|
||||
if (positionCounter % 2 == 0)
|
||||
credits->scrollTextBy(1);
|
||||
|
||||
//end of credits, close this screen
|
||||
if (credits->pos.y + credits->pos.h < 0)
|
||||
if (credits->textSize.y + 600 < positionCounter / 2)
|
||||
clickRight(false, false);
|
||||
}
|
||||
|
||||
@ -4091,45 +4077,51 @@ void CLoadingScreen::showAll(SDL_Surface *to)
|
||||
CWindowObject::showAll(to);
|
||||
}
|
||||
|
||||
CPrologEpilogVideo::CPrologEpilogVideo( CCampaignScenario::SScenarioPrologEpilog _spe, std::function<void()> callback )
|
||||
: spe(_spe), decrementDelayCounter(0), exitCb(callback)
|
||||
CPrologEpilogVideo::CPrologEpilogVideo( CCampaignScenario::SScenarioPrologEpilog _spe, std::function<void()> callback ):
|
||||
CWindowObject(BORDERED),
|
||||
spe(_spe),
|
||||
positionCounter(0),
|
||||
voiceSoundHandle(-1),
|
||||
exitCb(callback)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
addUsedEvents(LCLICK);
|
||||
pos = Rect(screen);
|
||||
pos = center(Rect(0,0, 800, 600));
|
||||
updateShadow();
|
||||
|
||||
CCS->videoh->open(CCampaignHandler::prologVideoName(spe.prologVideo));
|
||||
CCS->musich->playMusic("Music/" + CCampaignHandler::prologMusicName(spe.prologMusic), true);
|
||||
voiceSoundHandle = CCS->soundh->playSound(CCampaignHandler::prologVoiceName(spe.prologVideo));
|
||||
|
||||
auto lines = CMessage::breakText(spe.prologText, 500, EFonts::FONT_BIG);
|
||||
|
||||
txt = CSDL_Ext::newSurface(500, 20 * lines.size() + 10);
|
||||
curTxtH = screen->h;
|
||||
graphics->fonts[FONT_BIG]->renderTextLinesCenter(txt, lines, Colors::METALLIC_GOLD, Point(txt->w/2, txt->h/2 + 5));
|
||||
text = new CMultiLineLabel(Rect(100, 500, 600, 100), EFonts::FONT_BIG, CENTER, Colors::METALLIC_GOLD, spe.prologText );
|
||||
text->scrollTextTo(-100);
|
||||
}
|
||||
|
||||
void CPrologEpilogVideo::show( SDL_Surface * to )
|
||||
{
|
||||
memset(to->pixels, 0, to->h*to->pitch); //make bg black
|
||||
CCS->videoh->update(pos.x, pos.y, to, true, false);
|
||||
SDL_Rect tmp, our;
|
||||
our = Rect(0, to->h-100, to->w, 100);
|
||||
SDL_GetClipRect(to, &tmp);
|
||||
SDL_SetClipRect(to, &our);
|
||||
blitAt(txt, (to->w-txt->w)/2, curTxtH, to);
|
||||
SDL_SetClipRect(to, &tmp);
|
||||
CSDL_Ext::fillRect(to, &pos, 0); // fill screen with black
|
||||
//BUG: some videos are 800x600 in size while some are 800x400
|
||||
//VCMI should center them in the middle of the screen. Possible but needs modification
|
||||
//of video player API which I'd like to avoid untill we'll get rid of Windows-specific player
|
||||
CCS->videoh->update(pos.x, pos.y, to, false, false);
|
||||
|
||||
//move text every 5 calls/frames; seems to be good enough
|
||||
++decrementDelayCounter;
|
||||
if(decrementDelayCounter == 5)
|
||||
++positionCounter;
|
||||
if(positionCounter % 5 == 0)
|
||||
{
|
||||
curTxtH = std::max(curTxtH - 1, to->h - txt->h);
|
||||
decrementDelayCounter = 0;
|
||||
text->scrollTextBy(1);
|
||||
}
|
||||
else
|
||||
text->showAll(to);// blit text over video, if needed
|
||||
|
||||
if (text->textSize.y + 100 < positionCounter / 5)
|
||||
clickLeft(false, false);
|
||||
}
|
||||
|
||||
void CPrologEpilogVideo::clickLeft( tribool down, bool previousState )
|
||||
{
|
||||
GH.popInt(this);
|
||||
CCS->soundh->stopSound(voiceSoundHandle);
|
||||
exitCb();
|
||||
}
|
||||
|
||||
|
@ -89,12 +89,12 @@ public:
|
||||
|
||||
class CreditsScreen : public CIntObject
|
||||
{
|
||||
CTextBox* credits;
|
||||
int positionCounter;
|
||||
CMultiLineLabel* credits;
|
||||
public:
|
||||
CreditsScreen();
|
||||
|
||||
void show(SDL_Surface * to);
|
||||
void showAll(SDL_Surface * to);
|
||||
|
||||
void clickLeft(tribool down, bool previousState);
|
||||
void clickRight(tribool down, bool previousState);
|
||||
@ -434,12 +434,14 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class CPrologEpilogVideo : public CIntObject
|
||||
class CPrologEpilogVideo : public CWindowObject
|
||||
{
|
||||
CCampaignScenario::SScenarioPrologEpilog spe;
|
||||
SDL_Surface * txt;
|
||||
int curTxtH, decrementDelayCounter;
|
||||
int positionCounter;
|
||||
int voiceSoundHandle;
|
||||
std::function<void()> exitCb;
|
||||
|
||||
CMultiLineLabel * text;
|
||||
public:
|
||||
CPrologEpilogVideo(CCampaignScenario::SScenarioPrologEpilog _spe, std::function<void()> callback);
|
||||
|
||||
|
@ -142,9 +142,8 @@ void CQuestLog::init()
|
||||
quests[i].quest->getRolloverText (text, false);
|
||||
if (quests[i].obj)
|
||||
text.addReplacement (quests[i].obj->getHoverText()); //get name of the object
|
||||
CQuestLabel * label = new CQuestLabel (28, 199 + i * 24, FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
|
||||
CQuestLabel * label = new CQuestLabel (Rect(28, 199 + i * 24, 172,30), FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
|
||||
label->callback = boost::bind(&CQuestLog::selectQuest, this, i);
|
||||
label->setVisibleSize (Rect(0, 0, 172, 30));
|
||||
labels.push_back(label);
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,8 @@ class CQuestLabel : public LRClickableAreaWText, public CMultiLineLabel
|
||||
public:
|
||||
std::function<void()> callback;
|
||||
|
||||
CQuestLabel (int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "")
|
||||
: CMultiLineLabel (x, y, FONT_SMALL, TOPLEFT, Colors::WHITE, Text){};
|
||||
CQuestLabel (Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "")
|
||||
: CMultiLineLabel (position, FONT_SMALL, TOPLEFT, Colors::WHITE, Text){};
|
||||
void clickLeft(tribool down, bool previousState);
|
||||
void showAll(SDL_Surface * to);
|
||||
};
|
||||
|
@ -1204,10 +1204,12 @@ void CLabel::setText(const std::string &Txt)
|
||||
}
|
||||
}
|
||||
|
||||
CMultiLineLabel::CMultiLineLabel(int x, int y, EFonts Font, EAlignment Align, const SDL_Color &Color, const std::string &Text):
|
||||
CLabel(x, y, Font, Align, Color, Text),
|
||||
visibleSize(0, 0, 0, 0)
|
||||
CMultiLineLabel::CMultiLineLabel(Rect position, EFonts Font, EAlignment Align, const SDL_Color &Color, const std::string &Text):
|
||||
CLabel(position.x, position.y, Font, Align, Color, Text),
|
||||
visibleSize(0, 0, position.w, position.h)
|
||||
{
|
||||
pos.w = position.w;
|
||||
pos.h = position.h;
|
||||
splitText(Text);
|
||||
}
|
||||
|
||||
@ -1298,9 +1300,20 @@ void CMultiLineLabel::showAll(SDL_Surface * to)
|
||||
const IFont * f = graphics->fonts[font];
|
||||
|
||||
// calculate which lines should be visible
|
||||
size_t totalLines = lines.size();
|
||||
size_t beginLine = visibleSize.y / f->getLineHeight();
|
||||
size_t endLine = (getTextLocation().h + visibleSize.y) / f->getLineHeight() + 1;
|
||||
int totalLines = lines.size();
|
||||
int beginLine = visibleSize.y;
|
||||
int endLine = getTextLocation().h + visibleSize.y;
|
||||
|
||||
if (beginLine < 0)
|
||||
beginLine = 0;
|
||||
else
|
||||
beginLine /= f->getLineHeight();
|
||||
|
||||
if (endLine < 0)
|
||||
endLine = 0;
|
||||
else
|
||||
endLine /= f->getLineHeight();
|
||||
endLine++;
|
||||
|
||||
// and where they should be displayed
|
||||
Point lineStart = getTextLocation().topLeft() - visibleSize + Point(0, beginLine * f->getLineHeight());
|
||||
@ -1308,7 +1321,7 @@ void CMultiLineLabel::showAll(SDL_Surface * to)
|
||||
|
||||
CSDL_Ext::CClipRectGuard guard(to, getTextLocation()); // to properly trim text that is too big to fit
|
||||
|
||||
for (size_t i = beginLine; i < std::min(totalLines, endLine); i++)
|
||||
for (int i = beginLine; i < std::min(totalLines, endLine); i++)
|
||||
{
|
||||
if (!lines[i].empty()) //non-empty line
|
||||
blitLine(to, Rect(lineStart, lineSize), lines[i]);
|
||||
@ -1369,11 +1382,11 @@ CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts F
|
||||
slider(nullptr)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
label = new CMultiLineLabel(rect.x, rect.y, Font, Align, Color);
|
||||
label = new CMultiLineLabel(rect, Font, Align, Color);
|
||||
|
||||
type |= REDRAW_PARENT;
|
||||
label->pos.h = pos.h = rect.h;
|
||||
label->pos.w = pos.w = rect.w;
|
||||
pos.h = rect.h;
|
||||
pos.w = rect.w;
|
||||
|
||||
assert(pos.w >= 40); //we need some space
|
||||
setText(Text);
|
||||
|
@ -379,7 +379,7 @@ public:
|
||||
// total size of text, x = longest line of text, y = total height of lines
|
||||
Point textSize;
|
||||
|
||||
CMultiLineLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "");
|
||||
CMultiLineLabel(Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "");
|
||||
|
||||
void setText(const std::string &Txt);
|
||||
void showAll(SDL_Surface * to);
|
||||
|
@ -125,9 +125,11 @@
|
||||
"H3x2_UAl.smk", //UnholyAlliance_l
|
||||
"H3x2_UAm.smk", //UnholyAlliance_end //H3x2_UAm.bik?
|
||||
],
|
||||
"music" : [
|
||||
|
||||
"music" : [
|
||||
// Use CmpMusic.txt from H3 instead
|
||||
],
|
||||
|
||||
"voice" : [
|
||||
//Restoration of Erathia
|
||||
"G1A", //Long live the Queen 1
|
||||
|
@ -482,6 +482,20 @@ std::string CCampaignHandler::prologVideoName(ui8 index)
|
||||
|
||||
std::string CCampaignHandler::prologMusicName(ui8 index)
|
||||
{
|
||||
std::vector<std::string> music;
|
||||
|
||||
VLC->generaltexth->readToVector("Data/CmpMusic.txt", music);
|
||||
if(index < music.size())
|
||||
return music[index];
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string CCampaignHandler::prologVoiceName(ui8 index)
|
||||
{
|
||||
JsonNode config(ResourceID(std::string("CONFIG/campaignMedia"), EResType::TEXT));
|
||||
auto audio = config["voice"].Vector();
|
||||
if(index < audio.size())
|
||||
return audio[index].String();
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -181,6 +181,7 @@ class DLL_LINKAGE CCampaignHandler
|
||||
public:
|
||||
static std::string prologVideoName(ui8 index);
|
||||
static std::string prologMusicName(ui8 index);
|
||||
static std::string prologVoiceName(ui8 index);
|
||||
|
||||
static CCampaignHeader getHeader( const std::string & name); //name - name of appropriate file
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user