Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CmpSelectDlg.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: CmpSelectDlg.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Mission Select Dialog Active Window class
13 */
14 
15 #include "MemDebug.h"
16 #include "CmpSelectDlg.h"
17 #include "ConfirmDlg.h"
18 #include "MenuScreen.h"
19 #include "Starshatter.h"
20 #include "Campaign.h"
21 #include "CampaignSaveGame.h"
22 #include "CombatGroup.h"
23 #include "ShipDesign.h"
24 #include "Player.h"
25 
26 #include "Game.h"
27 #include "DataLoader.h"
28 #include "Button.h"
29 #include "ListBox.h"
30 #include "Slider.h"
31 #include "Video.h"
32 #include "Keyboard.h"
33 #include "Mouse.h"
34 #include "ParseUtil.h"
35 #include "FormatUtil.h"
36 
37 // +--------------------------------------------------------------------+
38 // DECLARE MAPPING FUNCTIONS:
39 
42 DEF_MAP_CLIENT(CmpSelectDlg, OnDelete);
43 DEF_MAP_CLIENT(CmpSelectDlg, OnConfirmDelete);
44 DEF_MAP_CLIENT(CmpSelectDlg, OnAccept);
45 DEF_MAP_CLIENT(CmpSelectDlg, OnCancel);
46 DEF_MAP_CLIENT(CmpSelectDlg, OnCampaignSelect);
47 
48 // +--------------------------------------------------------------------+
49 
51 : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
52 lst_campaigns(0), btn_new(0), btn_saved(0), btn_delete(0),
53 btn_accept(0), btn_cancel(0), description(0), stars(0), campaign(0),
54 selected_mission(-1), show_saved(false), loading(false),
55 loaded(false), hproc(0)
56 {
58  select_msg = Game::GetText("CmpSelectDlg.select_msg");
59  Init(def);
60 }
61 
63 {
64  StopLoadProc();
65  images.destroy();
66 }
67 
68 // +--------------------------------------------------------------------+
69 
70 void
72 {
73  btn_new = (Button*) FindControl(100);
74  btn_saved = (Button*) FindControl(101);
75  btn_delete = (Button*) FindControl(102);
76  btn_accept = (Button*) FindControl( 1);
77  btn_cancel = (Button*) FindControl( 2);
78 
79  if (btn_new)
81 
82  if (btn_saved)
84 
85  if (btn_delete) {
86  btn_delete->SetEnabled(false);
89  }
90 
91  if (btn_accept) {
92  btn_accept->SetEnabled(false);
94  }
95 
96  if (btn_cancel) {
97  btn_cancel->SetEnabled(true);
99  }
100 
101  description = FindControl(200);
102 
104 
105  if (lst_campaigns)
107 
109 }
110 
111 // +--------------------------------------------------------------------+
112 
113 void
115 {
116  if (Keyboard::KeyDown(VK_RETURN)) {
117  if (btn_accept && btn_accept->IsEnabled())
118  OnAccept(0);
119  }
120 
121  AutoThreadSync a(sync);
122 
123  if (loaded) {
124  loaded = false;
125 
126  if (btn_cancel)
127  btn_cancel->SetEnabled(true);
128 
129  if (description && btn_accept) {
130  if (campaign) {
132 
133  if (load_index >= 0) {
134  if (lst_campaigns) {
135  images[load_index]->CopyBitmap(*campaign->GetImage(1));
137  }
138 
139  description->SetText(Text("<font Limerick12><color ffffff>") +
140  campaign->Name() +
141  Text("<font Verdana>\n\n") +
142  Text("<color ffff80>") +
143  Game::GetText("CmpSelectDlg.scenario") +
144  Text("<color ffffff>\n\t") +
145  campaign->Description());
146  }
147  else {
148  char time_buf[32];
149  char score_buf[32];
150 
151  double t = campaign->GetLoadTime() - campaign->GetStartTime();
152  FormatDayTime(time_buf, t);
153 
154  sprintf_s(score_buf, "%d", campaign->GetPlayerTeamScore());
155 
156  Text desc = Text("<font Limerick12><color ffffff>") +
157  campaign->Name() +
158  Text("<font Verdana>\n\n") +
159  Text("<color ffff80>") +
160  Game::GetText("CmpSelectDlg.scenario") +
161  Text("<color ffffff>\n\t") +
162  campaign->Description() +
163  Text("\n\n<color ffff80>") +
164  Game::GetText("CmpSelectDlg.campaign-time") +
165  Text("<color ffffff>\n\t") +
166  time_buf +
167  Text("\n\n<color ffff80>") +
168  Game::GetText("CmpSelectDlg.assignment") +
169  Text("<color ffffff>\n\t");
170 
171  if (campaign->GetPlayerGroup())
172  desc += campaign->GetPlayerGroup()->GetDescription();
173  else
174  desc += "n/a";
175 
176  desc += Text("\n\n<color ffff80>") +
177  Game::GetText("CmpSelectDlg.team-score") +
178  Text("<color ffffff>\n\t") +
179  score_buf;
180 
181  description->SetText(desc);
182  }
183 
184  btn_accept->SetEnabled(true);
185 
186  if (btn_delete)
188  }
189  else {
191  btn_accept->SetEnabled(true);
192  }
193  }
194  }
195 }
196 
197 bool
199 {
200  AutoThreadSync a(sync);
201  return !loading;
202 }
203 
204 // +--------------------------------------------------------------------+
205 
206 void
208 {
209  AutoThreadSync a(sync);
210 
211  if (loading && description) {
212  description->SetText(Game::GetText("CmpSelectDlg.already-loading"));
214  return;
215  }
216 
217  if (btn_new)
219 
220  if (btn_saved)
222 
223  if (btn_delete)
224  btn_delete->SetEnabled(false);
225 
226  if (lst_campaigns) {
227  images.destroy();
228 
233 
234  Player* player = Player::GetCurrentPlayer();
235  if (!player) return;
236 
238  while (++iter) {
239  Campaign* c = iter.value();
240 
242  Bitmap* bmp = new(__FILE__,__LINE__) Bitmap;
243  bmp->CopyBitmap(*c->GetImage(0));
244  images.append(bmp);
245 
246  int n = lst_campaigns->AddImage(bmp) - 1;
247  lst_campaigns->SetItemText(n, c->Name());
248 
249  // if campaign is not available, show the grayed-out image
250 
251 #ifdef STARSHATTER_DEMO_RELEASE
252  // DEMO VERSION (only one campaign):
253  if (c->GetCampaignId() > 2) {
254  images[n]->CopyBitmap(*c->GetImage(2));
256  }
257 
258 #else
259  // FULL GAME CRITERIA (based on player record):
260  if (c->GetCampaignId() > 2 && c->GetCampaignId() < 10 &&
261  !player->HasCompletedCampaign(c->GetCampaignId()-1)) {
262  images[n]->CopyBitmap(*c->GetImage(2));
264  }
265 
266  // Two additional sequences of ten campaigns (10-19 and 20-29)
267  // for mod authors to use:
268  else if (c->GetCampaignId() >= 10 && c->GetCampaignId() < 30 &&
269  (c->GetCampaignId() % 10) != 0 &&
270  !player->HasCompletedCampaign(c->GetCampaignId()-1)) {
271  images[n]->CopyBitmap(*c->GetImage(2));
273  }
274 
275  // NOTE: Campaigns 10, 20, and 30-99 are always enabled if they exist!
276 #endif
277  }
278  }
279  }
280 
281  if (description)
283 
284  if (btn_accept)
285  btn_accept->SetEnabled(false);
286 
287  show_saved = false;
288 }
289 
290 // +--------------------------------------------------------------------+
291 
292 void
294 {
295  AutoThreadSync a(sync);
296 
297  if (loading && description) {
298  description->SetText(Game::GetText("CmpSelectDlg.already-loading"));
300  return;
301  }
302 
303  if (btn_new)
305 
306  if (btn_saved)
308 
309  if (btn_delete)
310  btn_delete->SetEnabled(false);
311 
312  if (lst_campaigns) {
317 
318  List<Text> save_list;
319 
321  save_list.sort();
322 
323  for (int i = 0; i < save_list.size(); i++)
324  lst_campaigns->AddItem(*save_list[i]);
325 
326  save_list.destroy();
327  }
328 
329  if (description)
331 
332  if (btn_accept)
333  btn_accept->SetEnabled(false);
334 
335  show_saved = true;
336 }
337 
338 // +--------------------------------------------------------------------+
339 
340 void
342 {
343  if (description && lst_campaigns) {
344  AutoThreadSync a(sync);
345 
346  if (loading) {
347  description->SetText(Game::GetText("CmpSelectDlg.already-loading"));
349  return;
350  }
351 
352  load_index = -1;
353  load_file = "";
354 
355  Player* player = Player::GetCurrentPlayer();
356  if (!player) return;
357 
358  // NEW CAMPAIGN:
359  if (btn_new && btn_new->GetButtonState()) {
361 
362  for (int i = 0; i < lst_campaigns->NumItems(); i++) {
363  Campaign* c = list[i];
364 
365  // is campaign available?
366 
367 #ifdef STARSHATTER_DEMO_RELEASE
368  // DEMO VERSION (only one campaign):
369  if (c->GetCampaignId() <= 2)
370 #else
371  // FULL GAME CRITERIA (based on player record):
372  if (c->GetCampaignId() <= 2 ||
373  player->HasCompletedCampaign(c->GetCampaignId()-1))
374 #endif
375  {
376 
377  if (lst_campaigns->IsSelected(i)) {
378  images[i]->CopyBitmap(*c->GetImage(1));
380 
381  AutoThreadSync a(sync);
382  load_index = i;
383  }
384  else {
385  images[i]->CopyBitmap(*c->GetImage(0));
387  }
388  }
389 
390  // if not, then don't select
391  else {
392  images[i]->CopyBitmap(*c->GetImage(2));
394 
395  if (lst_campaigns->IsSelected(i)) {
397  }
398  }
399  }
400  }
401 
402  // SAVED CAMPAIGN:
403  else {
404  int seln = lst_campaigns->GetSelection();
405 
406  if (seln < 0) {
408  }
409 
410  else {
411  load_index = -1;
413  }
414  }
415 
416  if (btn_accept)
417  btn_accept->SetEnabled(false);
418  }
419 
420  if (!loading && (load_index >= 0 || load_file.length() > 0)) {
421  if (btn_cancel)
422  btn_cancel->SetEnabled(false);
423 
424  StartLoadProc();
425  }
426 }
427 
428 // +--------------------------------------------------------------------+
429 
430 void
432 {
435 }
436 
437 // +--------------------------------------------------------------------+
438 
439 void
441 {
443 }
444 
445 void
447 {
449 }
450 
451 void
453 {
454  load_file = "";
455 
456  if (lst_campaigns) {
457  int seln = lst_campaigns->GetSelection();
458 
459  if (seln < 0) {
461  btn_accept->SetEnabled(false);
462  }
463 
464  else {
465  load_index = -1;
467  }
468  }
469 
470  if (load_file.length()) {
471  ConfirmDlg* confirm = manager->GetConfirmDlg();
472  if (confirm) {
473  char msg[256];
474  sprintf_s(msg, Game::GetText("CmpSelectDlg.are-you-sure"), load_file.data());
475  confirm->SetMessage(msg);
476  confirm->SetTitle(Game::GetText("CmpSelectDlg.confirm"));
477 
479  }
480 
481  else {
482  OnConfirmDelete(event);
483  }
484  }
485 
487 }
488 
489 void
491 {
492  if (load_file.length()) {
494  }
495 
497 }
498 
499 // +--------------------------------------------------------------------+
500 
501 void
503 {
504  AutoThreadSync a(sync);
505 
506  if (loading)
507  return;
508 
509  // if this is to be a new campaign,
510  // re-instaniate the campaign object
511  if (btn_new->GetButtonState())
513  else
515 
516  Mouse::Show(false);
518 }
519 
520 void
522 {
523  manager->ShowMenuDlg();
524 }
525 
526 // +--------------------------------------------------------------------+
527 
528 DWORD WINAPI CmpSelectDlgLoadProc(LPVOID link);
529 
530 void
532 {
533  if (hproc != 0) {
534  DWORD result = 0;
535  GetExitCodeThread(hproc, &result);
536 
537  if (result != STILL_ACTIVE) {
538  CloseHandle(hproc);
539  hproc = 0;
540  }
541  else {
542  return;
543  }
544  }
545 
546  if (hproc == 0) {
547  campaign = 0;
548  loading = true;
549  loaded = false;
550 
551  if (description)
552  description->SetText(Game::GetText("CmpSelectDlg.loading"));
553 
554  DWORD thread_id = 0;
555  hproc = CreateThread(0, 4096, CmpSelectDlgLoadProc, (LPVOID) this, 0, &thread_id);
556 
557  if (hproc == 0) {
558  static int report = 10;
559  if (report > 0) {
560  ::Print("WARNING: CmpSelectDlg() failed to create thread (err=%08x)\n", GetLastError());
561  report--;
562 
563  if (report == 0)
564  ::Print(" Further warnings of this type will be supressed.\n");
565  }
566  }
567  }
568 }
569 
570 void
572 {
573  if (hproc != 0) {
574  WaitForSingleObject(hproc, 2500);
575  CloseHandle(hproc);
576  hproc = 0;
577  }
578 }
579 
580 DWORD WINAPI CmpSelectDlgLoadProc(LPVOID link)
581 {
582  CmpSelectDlg* dlg = (CmpSelectDlg*) link;
583 
584  if (dlg)
585  return dlg->LoadProc();
586 
587  return (DWORD) E_POINTER;
588 }
589 
590 DWORD
592 {
593  Campaign* c = 0;
594 
595  // NEW CAMPAIGN:
596  if (load_index >= 0) {
598 
599  if (load_index < list.size()) {
600  c = list[load_index];
601  c->Load();
602  }
603  }
604 
605  // SAVED CAMPAIGN:
606  else {
607  CampaignSaveGame savegame;
608  savegame.Load(load_file);
609  c = savegame.GetCampaign();
610  }
611 
612  sync.acquire();
613 
614  loading = false;
615  loaded = true;
616  campaign = c;
617 
618  sync.release();
619 
620  return 0;
621 }
622 
623 // +--------------------------------------------------------------------+