1 #include "EndLevelScoreScreen.h"
2 #include "../../GameApp/BaseGameApp.h"
3 #include "../../Resource/Loaders/PalLoader.h"
4 #include "../../Resource/Loaders/PcxLoader.h"
5 #include "../../Resource/Loaders/PidLoader.h"
6 #include "../../Graphics2D/Image.h"
7 
8 #include "../../Actor/ActorTemplates.h"
9 #include "../../Actor/Actor.h"
10 #include "../../Actor/Components/PositionComponent.h"
11 
12 #include "ScoreScreenProcesses.h"
13 
14 //=================================================================================================
15 //
16 // Global variables
17 //
18 //=================================================================================================
19 
20 static Point g_ScreenScale(1.0, 1.0);
21 
22 uint8_t g_ScoreScreenPalette[] =
23 {
24     0x00, 0x00, 0x00, // 0
25     255, 252, 202, // 1 - DONE
26     240, 238, 90, // 2 - DONE
27     223, 220, 76, // 3 - DONE
28     219, 217, 74, // 4 - DONE
29     210, 208, 72, // 5 - DONE
30     189, 187, 63, // 6 - DONE
31     154, 153, 52, // 7 - DONE
32     130, 115, 44, // 8 - DONE
33     98, 97, 33, // 9 - DONE
34     64, 63, 21, // 10 - DONE
35     41, 41, 14, // 11 - DONE
36     38, 35, 44, // 12 - DONE
37     13, 11, 113, // 13 - DONE
38     19, 19, 170, // 14 - DONE
39     0, 104, 144, // 15 - DONE
40     178, 187, 188, // 16 - DONE
41     18, 157, 18, // 17 - DONE
42     75, 74, 68, // 18 - DONE
43     112, 111, 105, // 19 - DONE
44     220, 96, 0, // 20 - DONE
45     99, 4, 0, // 21 - DONE
46     138, 138, 138, // 22 - DONE
47     125, 41, 0, // 23 - DONE
48     44, 44, 44, // 24 - DONE
49     53, 6, 0, // 25 - DONE
50     253, 247, 202, // 26 - DONE
51     0xFE, 0xF4, 0x91, // 27 - DONE
52     252, 236, 67, // 28 - DONE
53     247, 232, 11, // 29 - DONE
54     240, 212, 95, // 30 - DONE
55     224, 183, 31, // 31 - DONE
56     205, 156, 15, // 32 - DONE
57     190, 134, 18, // 33 - DONE
58     250, 238, 140, // 34 - DONE
59     239, 222, 97, // 35 - DONE
60     217, 201, 90, // 36 - DONE
61     194, 179, 78, // 37 - DONE
62     161, 149, 65, // 38 - DONE
63     129, 119, 52, // 39 - DONE
64     91, 0, 18, // 40 - DONE
65     251, 221, 29, // 41 - DONE
66     247, 227, 121, // 42 - DONE
67     219, 136, 15, // 43 - DONE
68     171, 73, 9, // 44 - DONE
69     125, 38, 17, // 45 - DONE
70     219, 217, 254, // 46 - DONE
71     143, 137, 251, // 47 - DONE
72     45, 40, 218, // 48 - DONE
73     7, 6, 182, // 49 - DONE
74     172, 251, 203, // 50 - DONE
75     21, 233, 60, // 51 - DONE
76     0, 158, 0, // 52 - DONE
77     0, 48, 0, // 53 - DONE
78     243, 199, 254, // 54 - DONE
79     0xFF, 0x00, 0xFF, // 55                 55
80     0x5B, 0x5F, 0xFF, // 56                 56
81     0x97, 0x9C, 0xFF, // 57                 57
82     254, 193, 194, // 58 - DONE
83     253, 56, 57, // 59 - DONE
84     247, 2, 3, // 60 - DONE
85     146, 11, 24, // 61 - DONE
86     250, 222, 109, // 62 - DONE
87     251, 239, 191, // 63 - DONE
88     242, 198, 81, // 64 - DONE
89     243, 187, 48, // 65 - DONE
90     205, 138, 15, // 66 - DONE
91     232, 152, 13, // 67 - DONE
92     157, 101, 24, // 68 - DONE
93     221, 150, 53, // 69 - DONE
94     199, 138, 57, // 70 - DONE
95     196, 112, 25, // 71 - DONE
96     143, 67, 10, // 72 - DONE
97     79, 36, 5, // 73 - DONE
98     0, 255, 156, // 74 - DONE
99     8, 48, 121, // 75 - DONE
100     255, 0, 255, // 76 - DONE
101     90, 10, 59, // 77 - DONE
102     250, 234, 152, // 78 - DONE
103     241, 188, 0, // 79 - DONE
104     238, 189, 37, // 80 - DONE
105     209, 117, 5, // 81 - DONE
106     145, 72, 6, // 82 - DONE
107     11, 174, 11, // 83 - DONE
108     127, 211, 129, // 84 - DONE
109     112, 50, 3, // 85 - DONE
110     9, 86, 0, // 86 - DONE
111     70, 208, 46, // 87 - DONE
112     0xF9, 0xDB, 0x42, // 88                 88
113     232, 251, 212, // 89 - DONE
114     86, 219, 212, // 90 - DONE
115     0xF0, 0x58, 0x02, // 91
116     34, 96, 250, // 92 - DONE
117     18, 100, 28, // 93 - DONE
118     55, 157, 56, // 94 - DONE
119     7, 52, 3, // 95 - DONE
120     120, 208, 110, // 96 - DONE
121     192, 109, 134, // 97 - DONE
122     197, 45, 93, // 98 - DONE
123     145, 18, 58, // 99 - DONE
124     95, 64, 28, // 100 - DONE
125     110, 74, 32, // 101 - DONE
126     18, 8, 43, // 102 - DONE
127     41, 0, 0, // 103 - DONE
128     106, 57, 8, // 104 - DONE
129     0xF3, 0xC3, 0x4D, // 105
130     0xF4, 0xD7, 0x5C, // 106
131     0xD7, 0xA8, 0x18, // 107
132     115, 90, 41, // 108 - DONE
133     115, 82, 33, // 109 - DONE
134     115, 75, 24, // 110 - DONE
135     114, 75, 16, // 111 - DONE
136     112, 66, 14, // 112 - DONE
137     109, 57, 16, // 113 - DONE
138     0x9A, 0x11, 0xC5, // 114                114
139     0x05, 0xFF, 0xA1, // 115                115
140     108, 49, 9, // 116 - DONE
141     99, 49, 16, // 117 - DONE
142     0xEC, 0x75, 0xFF, // 118                118
143     0xF8, 0x9F, 0xFF, // 119                119
144     90, 49, 5, // 120 - DONE
145     100, 41, 5, // 121 - DONE
146     90, 41, 8, // 122 - DONE
147     90, 41, 0, // 123 - DONE
148     81, 42, 8, // 124 - DONE
149     0xBC, 0x08, 0x7D, // 125                125
150     91, 32, 2, // 126 - DONE
151     80, 33, 8, // 127 - DONE
152     82, 33, 0, // 128 - DONE
153     0x9A, 0x53, 0x16, // 129                129
154     0x90, 0x40, 0x0D, // 130                130
155     82, 24, 0, // 131 - DONE
156     79, 24, 8, // 132 - DONE
157     74, 24, 0, // 133 - DONE
158     65, 24, 0, // 134 - DONE
159     75, 16, 0, // 135 - DONE
160     61, 16, 0, // 136 - DONE
161     43, 15, 0, // 137 - DONE
162     0xD4, 0x03, 0xC8, // 138                138
163     0xB8, 0x06, 0xAB, // 139                139
164     0x9C, 0x0C, 0x83, // 140                140
165     0x79, 0x05, 0x73, // 141                141
166     0x68, 0x03, 0x65, // 142                142
167     0x52, 0x00, 0x5B, // 143                143
168     0x9A, 0x9B, 0x9B, // 144                144
169     0xAB, 0xAB, 0xAB, // 145                145
170     0x47, 0x30, 0x13, // 146                146
171     0x5D, 0x3C, 0x14, // 147                147
172     0x71, 0x4B, 0x14, // 148                148
173     0x69, 0x42, 0x1D, // 149                149
174     0x51, 0x32, 0x14, // 150                150
175     10, 10, 10, // 151 - DONE
176     9, 9, 9, // 152 - DONE
177     0x38, 0x2E, 0x2E, // 153                153
178     0x61, 0x53, 0x48, // 154                154
179     0x88, 0x79, 0x60, // 155                155
180     130, 130, 130, // 156 - DONE
181     0xBC, 0x74, 0x83, // 157                157
182     100, 100, 100, // 158 - DONE
183     0x5E, 0x3E, 0x71, // 159                159
184     0x03, 0x21, 0x36, // 160                160
185     77, 77, 77, // 161 - DONE
186     0x03, 0x4F, 0x74, // 162                START
187     0x03, 0x59, 0x7F, // 163
188     58, 58, 58, // 164 - DONE
189     0x03, 0x75, 0xA3, // 165
190     0x03, 0x85, 0xBB, // 166
191     0x03, 0x94, 0xC3, // 167
192     0x00, 0x27, 0x4E, // 168
193     8, 8, 8, // 169 - DONE
194     114, 70, 88, // 170 - DONE
195     0x03, 0x03, 0x03, // 171
196     0x57, 0xA9, 0xC1, // 172
197     0x3F, 0x88, 0xA8, // 173
198     0x24, 0x56, 0x79, // 174
199     0x18, 0x39, 0x54, // 175
200     0x11, 0x25, 0x37, // 176                END
201     123, 132, 0, // 177 - DONE
202     97, 97, 7, // 178 - DONE
203     102, 91, 23, // 179 - DONE
204     137, 118, 32, // 180 - DONE
205     186, 176, 141, // 181 - DONE
206     134, 103, 3, // 182 - DONE
207     0x03, 0x07, 0x0B, // 183                183
208     0x02, 0x05, 0x08, // 184                184
209     148, 90, 0, // 185 - DONE
210     0x00, 0x01, 0x02, // 186                186
211     214, 135, 30, // 187 - DONE
212     240, 154, 52, // 188 - DONE
213     0x66, 0x0F, 0x08, // 189                189
214     215, 123, 26, // 190 - DONE
215     192, 109, 22, // 191 - DONE
216     214, 129, 41, // 192 - DONE
217     206, 109, 13, // 193 - DONE
218     221, 145, 71, // 194 - DONE
219     179, 91, 6, // 195 - DONE
220     241, 139, 41, // 196 - DONE
221     214, 110, 13, // 197 - DONE
222     236, 127, 30, // 198 - DONE
223     189, 92, 7, // 199 - DONE
224     206, 110, 26, // 200 - DONE
225     214, 111, 26, // 201 - DONE
226     210, 123, 51, // 202 - DONE
227     226, 112, 21, // 203 - DONE
228     202, 93, 7, // 204 - DONE
229     178, 82, 7, // 205 - DONE
230     201, 111, 41, // 206 - DONE
231     135, 99, 71, // 207 - DONE
232     170, 74, 0, // 208 - DONE
233     178, 86, 16, // 209 - DONE
234     189, 89, 16, // 210 - DONE
235     182, 91, 24, // 211 - DONE
236     154, 67, 5, // 212 - DONE
237     198, 92, 16, // 213 - DONE
238     189, 82, 7, // 214 - DONE
239     228, 113, 33, // 215 - DONE
240     170, 74, 8, // 216 - DONE
241     210, 94, 16, // 217 - DONE
242     198, 96, 27, // 218 - DONE
243     168, 66, 0, // 219 - DONE
244     178, 93, 38, // 220 - DONE
245     155, 115, 89, // 221 - DONE
246     212, 97, 25, // 222 - DONE
247     185, 74, 6, // 223 - DONE
248     143, 73, 30, // 224 - DONE
249     136, 50, 0, // 225 - DONE
250     170, 74, 19, // 226 - DONE
251     168, 66, 8, // 227 - DONE
252     152, 54, 0, // 228 - DONE
253     135, 51, 8, // 229 - DONE
254     189, 74, 17, // 230 - DONE
255     103, 34, 0, // 231 - DONE
256     125, 41, 0, // 232 - DONE
257     168, 66, 17, // 233 - DONE
258     152, 54, 8, // 234 - DONE
259     185, 62, 8, // 235 - DONE
260     167, 54, 5, // 236 - DONE
261     144, 41, 0, // 237 - DONE
262     87, 24, 0, // 238 - DONE
263     134, 51, 19, // 239 - DONE
264     68, 18, 0, // 240 - DONE
265     115, 30, 0, // 241 - DONE
266     129, 32, 0, // 242 - DONE
267     129, 38, 8, // 243 - DONE
268     103, 24, 0, // 244 - DONE
269     96, 31, 15, // 245 - DONE
270     82, 15, 0, // 246 - DONE
271     94, 16, 0, // 247 - DONE
272     61, 25, 20, // 248 - DONE
273     69, 8, 0, // 249 - DONE
274     53, 6, 0, // 250 - DONE
275     34, 3, 0, // 251 - DONE
276     0x00, 0x53, 0x98, // 252                252
277     8, 0, 0, // 253 - DONE
278     123, 49, 49, // 254 - DONE
279     0xFF, 0xFF, 0xFF, // 255                255
280 };
281 
282 //=================================================================================================
283 //
284 // Global helper functions
285 //
286 //=================================================================================================
287 
GetScreenRect()288 static SDL_Rect GetScreenRect()
289 {
290     Point windowSize = g_pApp->GetWindowSize();
291     Point scale = g_pApp->GetScale();
292     int targetWidth = (int)(windowSize.x / scale.x);
293     int targetHeight = (int)(windowSize.y / scale.y);
294 
295     return{ 0, 0, targetWidth, targetHeight };
296 }
297 
298 //=================================================================================================
299 //
300 // Events bound to this module
301 //
302 //=================================================================================================
303 
304 class EventData_ScoreScreen_Finished_Intro : public BaseEventData
305 {
306 public:
307     static const EventType sk_EventType;
308 
EventData_ScoreScreen_Finished_Intro()309     EventData_ScoreScreen_Finished_Intro() { }
310 
VGetEventType(void) const311     virtual const EventType& VGetEventType(void) const { return sk_EventType; }
VCopy() const312     virtual IEventDataPtr VCopy() const
313     {
314         return IEventDataPtr(new EventData_ScoreScreen_Finished_Intro());
315     }
VSerialize(std::ostringstream & out) const316     virtual void VSerialize(std::ostringstream& out) const { assert(false && "Cannot be serialized"); }
VDeserialize(std::istringstream & in)317     virtual void VDeserialize(std::istringstream& in) { assert(false && "Cannot be serialized"); }
318 
GetName(void) const319     virtual const char* GetName(void) const { return "EventData_ScoreScreen_Finished_Intro"; }
320 };
321 
322 const EventType EventData_ScoreScreen_Finished_Intro::sk_EventType(0xb71eff5b);
323 
324 //=================================================================================================
325 //
326 // ScreenElementScoreScreen
327 //
328 //=================================================================================================
329 
ScreenElementScoreScreen(SDL_Renderer * pRenderer)330 ScreenElementScoreScreen::ScreenElementScoreScreen(SDL_Renderer* pRenderer)
331     :
332     Scene(pRenderer),
333     m_pBackground(nullptr),
334     m_pRenderer(pRenderer),
335     m_bInScoreScreen(false),
336     m_State(ScoreScreenState_None),
337     m_NextLevelNumber(0),
338     m_ScorePointsOnLevelStart(0),
339     m_ScorePointsCollectedInLevel(0),
340     m_DisplayedLevelScore(0),
341     m_DisplayedGameScore(0)
342 {
343     IEventMgr::Get()->VAddListener(MakeDelegate(this, &ScreenElementScoreScreen::FinishedLoadingRowDelegate), EventData_Finished_Loading_Row::sk_EventType);
344     IEventMgr::Get()->VAddListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenFinishedIntroDelegate), EventData_ScoreScreen_Finished_Intro::sk_EventType);
345     IEventMgr::Get()->VAddListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenLevelScoreAddedDelegate), EventData_ScoreScreen_Level_Score_Added::sk_EventType);
346 }
347 
~ScreenElementScoreScreen()348 ScreenElementScoreScreen::~ScreenElementScoreScreen()
349 {
350     IEventMgr::Get()->VRemoveListener(MakeDelegate(this, &ScreenElementScoreScreen::FinishedLoadingRowDelegate), EventData_Finished_Loading_Row::sk_EventType);
351     IEventMgr::Get()->VRemoveListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenFinishedIntroDelegate), EventData_ScoreScreen_Finished_Intro::sk_EventType);
352     IEventMgr::Get()->VRemoveListener(MakeDelegate(this, &ScreenElementScoreScreen::ScoreScreenLevelScoreAddedDelegate), EventData_ScoreScreen_Level_Score_Added::sk_EventType);
353 
354     m_SpawnRowProcessList.clear();
355 
356     SAFE_DELETE(m_pProcessMgr);
357 
358     g_pApp->SetScale(m_OriginalScale);
359 }
360 
VOnUpdate(uint32 msDiff)361 void ScreenElementScoreScreen::VOnUpdate(uint32 msDiff)
362 {
363     m_pProcessMgr->UpdateProcesses(msDiff);
364 
365     Scene::OnUpdate(msDiff);
366 }
367 
VOnRender(uint32 msDiff)368 void ScreenElementScoreScreen::VOnRender(uint32 msDiff)
369 {
370     assert(m_pBackground != nullptr);
371 
372     SDL_Rect backgroundRect = GetScreenRect();
373     SDL_RenderCopy(m_pRenderer, m_pBackground->GetTexture(), &backgroundRect, NULL);
374     //LOG("Rendered. Image width: " + ToStr(m_pBackground->GetWidth()));
375 
376     Scene::OnRender();
377 }
378 
VOnEvent(SDL_Event & evt)379 bool ScreenElementScoreScreen::VOnEvent(SDL_Event& evt)
380 {
381     switch (evt.type)
382     {
383         case SDL_KEYDOWN:
384         {
385             if (evt.key.repeat == 0)
386             {
387                 if (SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_KP_ENTER ||
388                     SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_RETURN ||
389                     SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_SPACE ||
390                     SDL_GetScancodeFromKey(evt.key.keysym.sym) == SDL_SCANCODE_ESCAPE)
391                 {
392                     ForceNextState();
393                     return true;
394                 }
395             }
396             break;
397         }
398     }
399 
400     return false;
401 }
402 
ForceNextState()403 void ScreenElementScoreScreen::ForceNextState()
404 {
405     if (m_State == ScoreScreenState_Intro)
406     {
407         // Kill all pending processes
408         m_pProcessMgr->AbortAllProcesses(true);
409 
410         // Force transition
411         IEventDataPtr pFinishedIntroEvent(new EventData_ScoreScreen_Finished_Intro());
412         IEventMgr::Get()->VTriggerEvent(pFinishedIntroEvent);
413     }
414     else if (m_State == ScoreScreenState_SpawningScoreRows)
415     {
416         // Force all rows to spawn process
417         for (auto iter = m_ScoreRowList.begin(); iter != m_ScoreRowList.end();)
418         {
419             StrongProcessPtr pRowProcess(new SpawnScoreRowProcess((*iter)));
420             m_pProcessMgr->AttachProcess(pRowProcess);
421 
422             m_SpawnRowProcessList.push_back(pRowProcess);
423 
424             iter = m_ScoreRowList.erase(iter);
425         }
426 
427         // And force them to finish immediately
428         for (StrongProcessPtr pProc : m_SpawnRowProcessList)
429         {
430             if (SpawnScoreRowProcess* pSpawnRowProc = dynamic_cast<SpawnScoreRowProcess*>(pProc.get()))
431             {
432                 pSpawnRowProc->ForceSpawnImmediately();
433             }
434             else
435             {
436                 assert(false && "Could not cast");
437             }
438         }
439 
440         m_State = ScoreScreenState_Finished;
441     }
442     else if (m_State == ScoreScreenState_Finished)
443     {
444         // Dissolve rows
445         for (StrongProcessPtr pProc : m_SpawnRowProcessList)
446         {
447             if (SpawnScoreRowProcess* pSpawnRowProc = dynamic_cast<SpawnScoreRowProcess*>(pProc.get()))
448             {
449                 // Dissolve row
450             }
451             else
452             {
453                 assert(false && "Could not cast");
454             }
455         }
456 
457         // Load next level and wait for death
458         LoadNextLevel();
459 
460         m_State = ScoreScreenState_Exiting;
461     }
462     else if (m_State == ScoreScreenState_Exiting)
463     {
464         // Nothing to do here, really
465     }
466     else
467     {
468         LOG_ERROR("Invalid state: " + ToStr((int)m_State));
469         assert(false && "Invalid state");
470     }
471 }
472 
LoadNextLevel()473 void ScreenElementScoreScreen::LoadNextLevel()
474 {
475     if (m_State == ScoreScreenState_Exiting)
476     {
477         return;
478     }
479 
480     // Specify this
481     int nextLevelNum = m_NextLevelNumber;
482 
483     m_pProcessMgr->AbortAllProcesses(true);
484     SAFE_DELETE(m_pProcessMgr);
485     IEventMgr::Get()->VAbortAllEvents();
486 
487     IEventDataPtr pEvent(new EventData_Menu_LoadGame(nextLevelNum, false, 0));
488     IEventMgr::Get()->VQueueEvent(pEvent);
489 }
490 
FinishedLoadingRowDelegate(IEventDataPtr pEventData)491 void ScreenElementScoreScreen::FinishedLoadingRowDelegate(IEventDataPtr pEventData)
492 {
493     if (m_State == ScoreScreenState_Finished)
494     {
495         return;
496     }
497 
498     // Continue loading rows as long as its not empty
499     if (!m_ScoreRowList.empty())
500     {
501         ScoreRowDef row = m_ScoreRowList.front();
502 
503         StrongProcessPtr pRowProcess(new SpawnScoreRowProcess(row));
504         m_pProcessMgr->AttachProcess(pRowProcess);
505 
506         m_SpawnRowProcessList.push_back(pRowProcess);
507 
508         m_ScoreRowList.erase(m_ScoreRowList.begin());
509     }
510 
511     // No more rows, we can finish
512     if (m_ScoreRowList.empty())
513     {
514         m_State = ScoreScreenState_Finished;
515     }
516 }
517 
ScoreScreenFinishedIntroDelegate(IEventDataPtr pEventData)518 void ScreenElementScoreScreen::ScoreScreenFinishedIntroDelegate(IEventDataPtr pEventData)
519 {
520     // Already loaded score screen ?
521     if (m_State == ScoreScreenState_SpawningScoreRows ||
522         m_State == ScoreScreenState_Finished)
523     {
524         return;
525     }
526 
527     m_State = ScoreScreenState_SpawningScoreRows;
528 
529     assert(m_pScoreBackgroundImage != nullptr);
530     m_pBackground = m_pScoreBackgroundImage;
531 
532     // Destroy any spawned actors
533     for (auto actorIter : m_ActorMap)
534     {
535         IEventMgr::Get()->VQueueEvent(IEventDataPtr(new EventData_Destroy_Actor(actorIter.first)));
536     }
537 
538     // Create score numbers of how many score points we gained in game and in level
539 
540     //
541     // SYMBOL: GAME symbol
542     //
543     {
544         Point position(95, 465);
545         std::string symbolImagePath = "/STATES/BOOTY/IMAGES/SYMBOLS/GAME4.PID";
546 
547         StrongActorPtr pOfSymbolImageActor = SpawnImageActor(
548             symbolImagePath,
549             position);
550     }
551 
552     //
553     // NUMBERS: GAME total score
554     //
555     {
556         Point position(165, 465);
557 
558         AddNumberImageActorsToList(
559             m_ScorePointsOnLevelStart,
560             m_ScorePointsOnLevelStart + m_ScorePointsCollectedInLevel,
561             position,
562             m_GameScoreNumbersList);
563     }
564 
565     //
566     // SYMBOL: LEVEL symbol
567     //
568     {
569         Point position(425, 465);
570         std::string symbolImagePath = "/STATES/BOOTY/IMAGES/SYMBOLS/LEVEL5.PID";
571 
572         StrongActorPtr pOfSymbolImageActor = SpawnImageActor(
573             symbolImagePath,
574             position);
575     }
576 
577     //
578     // NUMBERS: LEVEL total score
579     //
580     {
581         Point position(495, 465);
582 
583         AddNumberImageActorsToList(
584             0,
585             m_ScorePointsCollectedInLevel,
586             position,
587             m_LevelScoreNumbersList);
588     }
589 
590     // Spawn first score row. When its loading is finished it will fire an event which we will catch
591 
592     assert(!m_ScoreRowList.empty());
593     ScoreRowDef row = m_ScoreRowList[0];
594 
595     StrongProcessPtr pRowProcess(new SpawnScoreRowProcess(row));
596     m_pProcessMgr->AttachProcess(pRowProcess);
597 
598     m_ScoreRowList.erase(m_ScoreRowList.begin());
599 }
600 
ScoreScreenLevelScoreAddedDelegate(IEventDataPtr pEventData)601 void ScreenElementScoreScreen::ScoreScreenLevelScoreAddedDelegate(IEventDataPtr pEventData)
602 {
603     shared_ptr<EventData_ScoreScreen_Level_Score_Added> pCastEventData =
604         static_pointer_cast<EventData_ScoreScreen_Level_Score_Added>(pEventData);
605 
606     m_DisplayedGameScore += pCastEventData->GetAddedScore();
607     m_DisplayedLevelScore += pCastEventData->GetAddedScore();
608 
609     // Update total game score
610     UpdateScoreImageNumbers(m_DisplayedGameScore, m_GameScoreNumbersList);
611 
612     // Update level score
613     UpdateScoreImageNumbers(m_DisplayedLevelScore, m_LevelScoreNumbersList);
614 }
615 
Initialize(TiXmlElement * pScoreScreenRootElem)616 bool ScreenElementScoreScreen::Initialize(TiXmlElement* pScoreScreenRootElem)
617 {
618     m_pProcessMgr = new ProcessMgr();
619     IEventMgr::Get()->VAbortAllEvents();
620 
621     m_State = ScoreScreenState_Intro;
622 
623     // Set correct palette
624     WapPal* pScoreScreenPalette = WAP_PalLoadFromData((char*)g_ScoreScreenPalette, 768);
625     assert(pScoreScreenPalette != NULL);
626     g_pApp->SetCurrentPalette(pScoreScreenPalette);
627 
628     // Setup background sound
629     SoundInfo backgroundSound;
630     if (TiXmlElement* pBackgroundSoundElem = pScoreScreenRootElem->FirstChildElement("BackgroundSound"))
631     {
632         ParseValueFromXmlElem(&backgroundSound.soundToPlay, pBackgroundSoundElem->FirstChildElement("SoundPath"));
633         ParseValueFromXmlElem(&backgroundSound.soundVolume, pBackgroundSoundElem->FirstChildElement("Volume"));
634         ParseValueFromXmlElem(&backgroundSound.isMusic, pBackgroundSoundElem->FirstChildElement("IsMusic"));
635     }
636     assert(ParseValueFromXmlElem(&backgroundSound.soundToPlay, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.SoundPath"));
637     assert(ParseValueFromXmlElem(&backgroundSound.soundVolume, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.Volume"));
638     assert(ParseValueFromXmlElem(&backgroundSound.isMusic, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.IsMusic"));
639     bool isLooping = true;
640     ParseValueFromXmlElem(&isLooping, pScoreScreenRootElem, "FinishedLevelScreen.BackgroundSound.IsLooping");
641     backgroundSound.loops = isLooping ? -1 : 0;
642     assert(!backgroundSound.soundToPlay.empty());
643     IEventMgr::Get()->VQueueEvent(IEventDataPtr(new EventData_Request_Play_Sound(backgroundSound)));
644 
645     // Setup intro background image
646     std::string initialBackgroundImagePath;
647     assert(ParseValueFromXmlElem(&initialBackgroundImagePath, pScoreScreenRootElem->FirstChildElement("InitialBackgroundScreen")));
648     m_pBackground = PcxResourceLoader::LoadAndReturnImage(initialBackgroundImagePath.c_str());
649 
650     // Setup score screen background image
651     std::string scoreBackgroundImagePath;
652     assert(ParseValueFromXmlElem(&scoreBackgroundImagePath, pScoreScreenRootElem->FirstChildElement("ScoreBackgroundScreen")));
653     m_pScoreBackgroundImage = PcxResourceLoader::LoadAndReturnImage(scoreBackgroundImagePath.c_str());
654 
655     if (TiXmlElement* pAcquiredPieceElem = pScoreScreenRootElem->FirstChildElement("AcquiredPiece"))
656     {
657         std::string acquiredPieceImagePath;
658         Point acquiredPiecePosition;
659         AnimationDef aniDef;
660         int delay;
661         std::string sound;
662 
663         assert(ParseValueFromXmlElem(&acquiredPieceImagePath, pAcquiredPieceElem->FirstChildElement("ImagePath")));
664         assert(ParseValueFromXmlElem(&acquiredPiecePosition, pAcquiredPieceElem->FirstChildElement("Position"), "x", "y"));
665         assert(ParseValueFromXmlElem(&delay, pAcquiredPieceElem->FirstChildElement("Delay")));
666         assert(ParseValueFromXmlElem(&sound, pAcquiredPieceElem->FirstChildElement("SoundPath")));
667         if (TiXmlElement* pAnimElem = pAcquiredPieceElem->FirstChildElement("AnimationDef"))
668         {
669             assert(ParseValueFromXmlElem(&aniDef.hasAnimation, pAnimElem->FirstChildElement("HasAnimation")));
670             assert(ParseValueFromXmlElem(&aniDef.isCycleAnimation, pAnimElem->FirstChildElement("IsCycleAnimation")));
671             assert(ParseValueFromXmlElem(&aniDef.cycleAnimationDuration, pAnimElem->FirstChildElement("CycleDuration")));
672         }
673 
674         StrongProcessPtr pShowAcquiredPieceImageProc(new ImageSpawnProcess(
675             acquiredPieceImagePath,
676             acquiredPiecePosition,
677             aniDef));
678         QueueDelayedProcess(pShowAcquiredPieceImageProc, delay);
679 
680         SoundInfo soundInfo(sound);
681         StrongProcessPtr pAcquiredPieceSoundProc(new PlaySoundProcess(soundInfo));
682         QueueDelayedProcess(pAcquiredPieceSoundProc, delay);
683     }
684     else
685     {
686         //assert(false && "Acquired piece XML element is missing");
687         LOG_WARNING("Acquired piece element is not present !");
688     }
689 
690     int clawFinishDialogTime = 0;
691     if (TiXmlElement* pClawCommentSound = pScoreScreenRootElem->FirstChildElement("ClawCommentSound"))
692     {
693         int delay;
694         std::string sound;
695 
696         assert(ParseValueFromXmlElem(&delay, pClawCommentSound->FirstChildElement("Delay")));
697         assert(ParseValueFromXmlElem(&sound, pClawCommentSound->FirstChildElement("SoundPath")));
698 
699         SoundInfo soundInfo(sound);
700         StrongProcessPtr pClawCommentSoundProc(new PlaySoundProcess(soundInfo));
701         QueueDelayedProcess(pClawCommentSoundProc, delay);
702 
703         clawFinishDialogTime = delay + Util::GetSoundDurationMs(sound);
704     }
705     else
706     {
707         assert(false && "Claw comment sound XML element is missing");
708     }
709 
710     assert(clawFinishDialogTime != 0);
711     //LOG("Claw will finish dialog in: " + ToStr(clawFinishDialogTime));
712 
713     IEventDataPtr pFinishedIntroEvent(new EventData_ScoreScreen_Finished_Intro());
714     StrongProcessPtr pSpawnFinishedIntroProcess(new FireEventProcess(pFinishedIntroEvent, true));
715     QueueDelayedProcess(pSpawnFinishedIntroProcess, clawFinishDialogTime);
716 
717     // Lets just assume that the background will take the whole screen
718     // From that we can calculate current scale (can't use predefined scale here)
719     m_OriginalScale = g_pApp->GetScale();
720     Point windowSize = g_pApp->GetWindowSize();
721     g_ScreenScale.Set(windowSize.x / m_pBackground->GetWidth(), windowSize.y / m_pBackground->GetHeight());
722     g_pApp->SetScale(g_ScreenScale);
723 
724     // Load score rows
725     for (TiXmlElement* pScoreRowElem = pScoreScreenRootElem->FirstChildElement("ScoreRow");
726         pScoreRowElem != NULL;
727         pScoreRowElem = pScoreRowElem->NextSiblingElement("ScoreRow"))
728     {
729         ScoreRowDef scoreRowDef;
730 
731         assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemImagePath,
732             pScoreRowElem->FirstChildElement("ScoreItemImagePath")));
733         assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemPickupSound,
734             pScoreRowElem->FirstChildElement("ScoreItemPickupSound")));
735         assert(ParseValueFromXmlElem(&scoreRowDef.rowStartPosition,
736             pScoreRowElem->FirstChildElement("RowStartPosition"), "x", "y"));
737         assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemPointsWorth,
738             pScoreRowElem->FirstChildElement("ScoreItemPointsWorth")));
739         assert(ParseValueFromXmlElem(&scoreRowDef.countOfPickedUpScoreItems,
740             pScoreRowElem->FirstChildElement("CountOfPickedUpScoreItems")));
741         assert(ParseValueFromXmlElem(&scoreRowDef.countOfMapScoreItems,
742             pScoreRowElem->FirstChildElement("CountOfTotalScoreItemsInLevel")));
743         assert(ParseValueFromXmlElem(&scoreRowDef.collectedScoreItemSpawnPosition,
744             pScoreRowElem->FirstChildElement("CollectedScoreItemSpawnPosition"), "x", "y"));
745 
746         if (TiXmlElement* pScoreItemAnimElem = pScoreRowElem->FirstChildElement("ScoreItemAnimation"))
747         {
748             assert(ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.hasAnimation,
749                 pScoreItemAnimElem->FirstChildElement("HasAnimation")));
750 
751             ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.isCycleAnimation,
752                 pScoreItemAnimElem->FirstChildElement("IsCycleAnimation"));
753             ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.cycleAnimationDuration,
754                 pScoreItemAnimElem->FirstChildElement("CycleDuration"));
755             ParseValueFromXmlElem(&scoreRowDef.scoreItemAnimationDef.animationPath,
756                 pScoreItemAnimElem->FirstChildElement("AnimationPath"));
757         }
758 
759         if (TiXmlElement* pAlternativeImagesElem = pScoreRowElem->FirstChildElement("AlternativeImages"))
760         {
761             for (TiXmlElement* pAltImageElem = pAlternativeImagesElem->FirstChildElement("AlternativeImage");
762                 pAltImageElem != NULL;
763                 pAltImageElem = pAltImageElem->NextSiblingElement("AlternativeImage"))
764             {
765                 std::string alternativeImage;
766                 assert(ParseValueFromXmlElem(&alternativeImage, pAltImageElem));
767 
768                 scoreRowDef.alternativeImagesList.push_back(alternativeImage);
769             }
770         }
771 
772         m_ScoreRowList.push_back(scoreRowDef);
773     }
774 
775     // Info about finished level
776     assert(ParseValueFromXmlElem(&m_NextLevelNumber, pScoreScreenRootElem,
777         "FinishedLevelScreen.NextLevelNumber"));
778     assert(ParseValueFromXmlElem(&m_ScorePointsOnLevelStart, pScoreScreenRootElem,
779         "FinishedLevelScreen.ScorePointsOnLevelStart"));
780     assert(ParseValueFromXmlElem(&m_ScorePointsCollectedInLevel, pScoreScreenRootElem,
781         "FinishedLevelScreen.ScorePointsCollectedInLevel"));
782 
783     return true;
784 };
785 
QueueDelayedProcess(StrongProcessPtr pProcess,int delay)786 void ScreenElementScoreScreen::QueueDelayedProcess(StrongProcessPtr pProcess, int delay)
787 {
788     StrongProcessPtr pDelayProc = StrongProcessPtr(new DelayedProcess(delay));
789     pDelayProc->AttachChild(pProcess);
790     m_pProcessMgr->AttachProcess(pDelayProc);
791 }