Skip to content

Commit 999721b

Browse files
committed
feat(intro): Add short Intro Logo for The Super Hackers team
1 parent 2f3ca08 commit 999721b

5 files changed

Lines changed: 224 additions & 1 deletion

File tree

Core/GameEngine/Include/GameClient/Intro.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,48 @@
1818

1919
#pragma once
2020

21+
#include <vector>
22+
23+
class DisplayString;
24+
class Image;
25+
2126
class Intro
2227
{
2328
enum IntroState
2429
{
2530
IntroState_Start,
2631
IntroState_EALogoMovie,
32+
IntroState_TheSuperHackersWait,
33+
IntroState_TheSuperHackers,
2734
IntroState_SizzleMovieWait,
2835
IntroState_SizzleMovie,
2936
IntroState_Done,
3037
};
3138

39+
struct DisplayEntity
40+
{
41+
DisplayEntity()
42+
: displayString(nullptr)
43+
, image(nullptr)
44+
, sizeX(10)
45+
, sizeY(10)
46+
, screenHeightFactor(0.5f)
47+
{}
48+
~DisplayEntity();
49+
50+
DisplayString* displayString;
51+
const Image* image;
52+
Int sizeX;
53+
Int sizeY;
54+
Real screenHeightFactor; // 0..1
55+
};
56+
3257
public:
3358

3459
Intro();
3560

3661
void update();
62+
void draw();
3763

3864
void enterNextState();
3965

@@ -42,11 +68,18 @@ class Intro
4268
private:
4369

4470
void doEALogoMovie();
71+
void doTheSuperHackers();
4572
void doSizzleMovie();
4673
void doPostIntro();
4774
void doAsyncWait(UnsignedInt milliseconds);
4875

76+
void drawDisplayEntities();
77+
78+
private:
79+
4980
IntroState m_currentState;
5081
UnsignedInt m_allowedStateFlags;
5182
UnsignedInt m_waitUntilMs;
83+
std::vector<DisplayEntity> m_displayEntities;
84+
Real m_fadeValue;
5285
};

Core/GameEngine/Source/GameClient/Intro.cpp

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,34 @@
1919
#include "PreRTS.h"
2020
#include "GameClient/Intro.h"
2121

22+
#include "Common/FramePacer.h"
2223
#include "Common/GameLOD.h"
2324

2425
#include "GameClient/Display.h"
26+
#include "GameClient/DisplayStringManager.h"
2527
#include "GameClient/GameWindowManager.h"
28+
#include "GameClient/GlobalLanguage.h"
29+
#include "GameClient/Image.h"
2630

2731

32+
Intro::DisplayEntity::~DisplayEntity()
33+
{
34+
TheDisplayStringManager->freeDisplayString(displayString);
35+
}
36+
2837
Intro::Intro()
2938
: m_currentState(IntroState_Start)
3039
, m_allowedStateFlags(0)
3140
, m_waitUntilMs(0)
41+
, m_fadeValue(0.0f)
3242
{
3343
if (TheGlobalData->m_playIntro)
3444
{
45+
// Please be kind and do not remove the EA logo movie. This game was built by EA. It lasts just 3 seconds.
3546
m_allowedStateFlags |= 1u << IntroState_EALogoMovie;
47+
// Please be kind and do not remove the custom logo screen when building on top of the work of The Super Hackers.
48+
m_allowedStateFlags |= 1u << IntroState_TheSuperHackersWait;
49+
m_allowedStateFlags |= 1u << IntroState_TheSuperHackers;
3650
}
3751

3852
if (TheGlobalData->m_playSizzle)
@@ -69,13 +83,23 @@ void Intro::update()
6983
switch (m_currentState)
7084
{
7185
case IntroState_EALogoMovie: doEALogoMovie(); break;
86+
case IntroState_TheSuperHackersWait: doAsyncWait(800); break;
87+
case IntroState_TheSuperHackers: doTheSuperHackers(); break;
7288
case IntroState_SizzleMovieWait: doAsyncWait(1000); break;
7389
case IntroState_SizzleMovie: doSizzleMovie(); break;
7490
case IntroState_Done: doPostIntro(); break;
7591
}
7692
}
7793
}
7894

95+
void Intro::draw()
96+
{
97+
switch (m_currentState)
98+
{
99+
case IntroState_TheSuperHackers: drawDisplayEntities(); break;
100+
}
101+
}
102+
79103
void Intro::doEALogoMovie()
80104
{
81105
TheWritableGlobalData->m_allowExitOutOfMovies = FALSE;
@@ -85,6 +109,110 @@ void Intro::doEALogoMovie()
85109
TheDisplay->playMovie("EALogoMovie640");
86110
}
87111

112+
void Intro::doTheSuperHackers()
113+
{
114+
struct Setting
115+
{
116+
Setting()
117+
: imageName(nullptr)
118+
, text(nullptr)
119+
, screenHeightFactor(0.5f)
120+
, sizeX(10)
121+
, sizeY(10)
122+
, bold(false)
123+
, centered(false)
124+
{}
125+
126+
const Char* imageName;
127+
const WideChar* text;
128+
Real screenHeightFactor;
129+
Int sizeX;
130+
Int sizeY;
131+
Bool bold;
132+
Bool centered;
133+
};
134+
135+
std::vector<Setting> settings;
136+
137+
{
138+
// China Hacker image
139+
Setting setting;
140+
setting.imageName = "SNHacker2_L";
141+
setting.screenHeightFactor = 0.15f;
142+
setting.sizeX = (Int)(122 * 0.70f);
143+
setting.sizeY = (Int)(98 * 0.70f);
144+
settings.push_back(setting);
145+
}
146+
{
147+
// Team name
148+
Setting setting;
149+
setting.text = L"The Super Hackers";
150+
setting.screenHeightFactor = 0.35f;
151+
setting.sizeY = 30;
152+
setting.bold = true;
153+
setting.centered = true;
154+
settings.push_back(setting);
155+
}
156+
{
157+
// Website
158+
Setting setting;
159+
setting.text = L"www.github.com/TheSuperHackers";
160+
setting.screenHeightFactor = 0.45f;
161+
setting.sizeY = 15;
162+
setting.bold = false;
163+
setting.centered = true;
164+
settings.push_back(setting);
165+
}
166+
{
167+
// Code contributors with 10 or more commits to main branch.
168+
// Sort by alphabet or commit count.
169+
Setting setting;
170+
setting.text =
171+
L"bobtista "
172+
L"Caball009 "
173+
L"feliwir "
174+
L"helmutbuhler\n"
175+
L"JohnsterID "
176+
L"Mauller "
177+
L"OmniBlade "
178+
L"SkyAero\n"
179+
L"slurmlord "
180+
L"Stubbjax "
181+
L"tomsons26 "
182+
L"xezon\n";
183+
setting.screenHeightFactor = 0.55f;
184+
setting.sizeY = 12;
185+
setting.bold = false;
186+
setting.centered = true;
187+
settings.push_back(setting);
188+
}
189+
190+
m_displayEntities.resize(settings.size());
191+
192+
for (size_t i = 0; i < m_displayEntities.size(); ++i)
193+
{
194+
Setting& s = settings[i];
195+
DisplayEntity& e = m_displayEntities[i];
196+
e.sizeX = TheGlobalLanguageData->adjustFontSize(s.sizeX);
197+
e.sizeY = TheGlobalLanguageData->adjustFontSize(s.sizeY);
198+
if (s.text != nullptr)
199+
{
200+
e.displayString = TheDisplayStringManager->newDisplayString();
201+
e.displayString->setText(s.text);
202+
e.displayString->setFont(TheFontLibrary->getFont("Cascadia Code", e.sizeY, s.bold));
203+
e.displayString->setWordWrapCentered(s.centered);
204+
}
205+
if (s.imageName != nullptr)
206+
{
207+
e.image = TheMappedImageCollection->findImageByName(s.imageName);
208+
}
209+
e.screenHeightFactor = s.screenHeightFactor;
210+
}
211+
212+
doAsyncWait(3000);
213+
m_fadeValue = 0.0f;
214+
}
215+
88216
void Intro::doSizzleMovie()
89217
{
90218
TheWritableGlobalData->m_allowExitOutOfMovies = TRUE;
@@ -104,3 +232,56 @@ void Intro::doAsyncWait(UnsignedInt milliseconds)
104232
{
105233
m_waitUntilMs = timeGetTime() + milliseconds;
106234
}
235+
236+
void Intro::drawDisplayEntities()
237+
{
238+
const Real alpha = 255.0f * clamp(0.0f, m_fadeValue, 1.0f);
239+
const Color color = GameMakeColor(255, 255, 255, (Int)alpha);
240+
const Color dropColor = GameMakeColor(255, 255, 255, 0);
241+
const Int screenWidth = TheDisplay->getWidth();
242+
const Int screenHeight = TheDisplay->getHeight();
243+
244+
for (size_t i = 0; i < m_displayEntities.size(); ++i)
245+
{
246+
DisplayEntity& e = m_displayEntities[i];
247+
if (e.displayString != nullptr)
248+
{
249+
ICoord2D pos;
250+
e.displayString->getSize(&pos.x, &pos.y);
251+
pos.x = (screenWidth / 2) - (pos.x / 2);
252+
pos.y = (Int)(e.screenHeightFactor * screenHeight);
253+
e.displayString->setWordWrap(screenWidth);
254+
e.displayString->draw(pos.x, pos.y, color, dropColor);
255+
}
256+
if (e.image != nullptr)
257+
{
258+
IRegion2D region;
259+
region.lo.x = (screenWidth / 2) - (e.sizeX / 2);
260+
region.hi.x = (screenWidth / 2) + (e.sizeX / 2);
261+
region.lo.y = (Int)(e.screenHeightFactor * screenHeight);
262+
region.hi.y = region.lo.y + e.sizeY;
263+
TheDisplay->drawImage(e.image, region.lo.x, region.lo.y, region.hi.x, region.hi.y, color);
264+
}
265+
}
266+
267+
constexpr const Real fadeInMs = 500.f;
268+
constexpr const Real fadeOutMs = 125.f;
269+
270+
if (timeGetTime() + fadeOutMs > m_waitUntilMs)
271+
{
272+
if (m_fadeValue > 0.0f)
273+
{
274+
// Fade out
275+
m_fadeValue -= TheFramePacer->getUpdateTime() * (1000.f / fadeOutMs);
276+
if (m_fadeValue < 0.0f)
277+
m_fadeValue = 0.0f;
278+
}
279+
}
280+
else if (m_fadeValue < 1.0f)
281+
{
282+
// Fade in
283+
m_fadeValue += TheFramePacer->getUpdateTime() * (1000.f / fadeInMs);
284+
if (m_fadeValue > 1.0f)
285+
m_fadeValue = 1.0f;
286+
}
287+
}

GeneralsMD/Code/GameEngine/Include/GameClient/GameClient.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class GameClient : public SubsystemInterface,
9292
// subsystem methods
9393
virtual void init( void ); ///< Initialize resources
9494
virtual void update( void ); ///< Updates the GUI, display, audio, etc
95+
virtual void draw();
9596
virtual void reset( void ); ///< reset system
9697

9798
virtual void setFrame( UnsignedInt frame ) { m_frame = frame; } ///< Set the GameClient's internal frame number

GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,14 @@ void GameClient::update( void )
730730
}
731731
}
732732

733+
void GameClient::draw()
734+
{
735+
if (m_intro != nullptr)
736+
{
737+
m_intro->draw();
738+
}
739+
}
740+
733741
void GameClient::step()
734742
{
735743
TheDisplay->step();

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,7 @@ void W3DDisplay::draw( void )
18591859
// draw the user interface
18601860
TheInGameUI->DRAW();
18611861

1862-
// end of video example code
1862+
TheGameClient->DRAW();
18631863

18641864
// draw the mouse
18651865
if( TheMouse )

0 commit comments

Comments
 (0)